2016-12-05 17:02:29 +00:00
|
|
|
/*
|
2023-11-03 23:21:46 +00:00
|
|
|
Copyright 2016-2023 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/.
|
|
|
|
*/
|
|
|
|
|
2023-11-08 21:21:21 +00:00
|
|
|
#include <assert.h>
|
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"
|
Refactor how save data (including SD cards) is initialized (#1898)
* Remove `FATStorage::Open` and `FATStorage::Close`
- That's what the constructor and destructor are for, respectively
* Add `FATStorage::IsReadOnly`
* Slight cleanup of `FATStorage`
- Make it move-constructible and move-assignable
- Represent the absence of a sync directory with `std::optional`, not an empty string
- Add `FATStorageArgs` for later use
* Refactor `CartHomebrew` to accept an optional `FATStorageArgs`
- `CartHomebrew` uses it to load an SD card image
- Not passing a `FATStorage` directly because we won't know if we need to load the card until we parse the ROM
- Store the `FATStorage` inside a `std::optional` instead of a pointer
- `CartHomebrew::Reset` no longer reloads the SD card; the frontend needs to set it with the `SetSDCard` method
* Close `NANDImage::CurFile` when move-assigning
- Whoops
* Add `Args.h`
- To construct a `NDS` or `DSi` with arguments
- Mostly intended for system files
* Fix incorrect `final` placement
* Refactor how `DSi`'s NAND and SD card are set
- Provide them via a `DSiArgs` argument in the constructor
- Give `DSi_MMCStorage` ownership of the `NANDImage` or `FATStorage` as needed, and expose getters/setters
- Replace `DSi_SDHost::Ports` with a `array<unique_ptr, 2>` to reduce the risk of leaks
- Store `DSi_MMCStorage`'s disk images in a `std::variant`
- The SD card and NAND image are no longer reset in `Reset()`; the frontend will need to do that itself
* Add getters/setters on `DSi` itself for its storage media
* Remove newly-unused `Platform::ConfigEntry`s
* Use `DSi::SetNAND` in the frontend
* Add `EmuThread::NeedToRecreateConsole`
* Document `NDSArgs` and give its fields default values
* Refactor how system files are loaded upon construction
- Pass `NDSArgs&&` into `NDS`'s constructor
- Use `std::array` for the emulator's BIOS images and the built-in FreeBIOS, to simplify copying and comparison
- Initialize the BIOS, firmware, and SD cards from `NDSArgs` or `DSiArgs`
- Add a new default constructor for `NDS` (not `DSi`) that initializes the DS with default system files
- Embed `FirmwareMem::Firmware` directly instead of in a `unique_ptr`
- `SPIHost` now takes a `Firmware&&` that it forwards to `FirmwareMem`
- Add `Firmware` getters/setters plus `const` variants for `NDS`, `Firmware`, and `FirmwareMem`
- Simplify installation of firmware
* Initialize the DSi BIOS in the constructor
- Change `DSi::ARM9iBIOS` and `ARM7iBIOS` to `std::array`
* Update the frontend to reflect the core's changes
* Remove `DSi_SDHost::CloseHandles`
* Pass `nullopt` instead of the empty string when folder sync is off
* Deduplicate ROM extraction logic
- `LoadGBAROM` and `LoadROM` now delegate to `LoadROMData`
- Also use `unique_ptr` instead of `new[]`
* Oops, missed some `get()`'s
* Move `NDS::IsLoadedARM9BIOSBuiltIn` to the header
- So it's likelier to be inlined
- Same for the ARM7 version
* Remove `NDS::SetConsoleType`
* Add `NDS::SetFirmware`
* Move `GBACart::SetupSave` to be `protected`
- It was only ever used inside the class
* Rename `GBACart::LoadSave` to `SetSaveMemory`
- Same for the cart slot
* Declare `GBACartSlot` as a friend of `GBACart::CartCommon`
* Revise `GBACartSlot`'s getters and setters
- Rename `InsertROM` and `LoadROM` to `SetCart`
- Add a `GetCart` method
* Clean up getters and setters for NDS and GBA carts
* Clean up how carts are inserted into the slots
- Remove setters that operate directly on pointers, to simplify error-handling (use ParseROM instead)
- Add overloads for all carts that accept a `const u8*` (to copy the ROM data) and a `unique_ptr<u8[]>` (to move the ROM data)
- Store all ROM and RAM data in `unique_ptr`
- Default-initialize all fields
- Simplify constructors and destructors, inheriting where applicable
* Refactor GBA save data insertion
- Make `SetupSave` private and non-virtual and move its logic to be in `SetSaveMemory`
- Add overloads for setting save data in the constructor
- Update the SRAM completely in `SetSaveMemory`
* Clean up `NDSCart::CartCommon::SetSaveMemory`
- Move its declaration next to the other `SaveMemory` methods
- Move its (empty) implementation to the header
* Add some comments
* Add Utils.cpp and Utils.h
* Rename some functions in Utils for clarity
* Add `GBACart::ParseROM` and `NDSCart::ParseROM` overloads that accept `unique_ptr<u8[]>`
- The `u8*` overloads delegate to these new overloads
- Also move `SetupSave` for both kinds of carts to be private non-virtual methods
* Finalize the `NDSCart` refactor
- Add `NDSCartArgs` to pass to `ParseROM`
- Add SRAM arguments for all retail carts
- Initialize SRAM inside the constructor
- Delegate to other constructors where possible
* Replace `ROMManager::NDSSave` and `GBASave` with `unique_ptr`
* Make both cart slots return the previously-inserted cart in `EjectCart`
- Primarily intended for reusing carts when resetting the console
* Make `NDS::EjectCart` return the old cart
* Initialize both cart slots with the provided ROM (if any)
* Make `NDS::EjectGBACart` return the ejected cart
* Clean up some comments in Args.h
* Rename `ROMManager::LoadBIOS` to `BootToMenu`
- Clarifies the intent
* Add `ROMManager::LoadDLDISDCard`
* Add a doc comment
* Refactor how the `NDS` is created or updated
- Rewrite `CreateConsole` to read from `Config` and load system files, but accept carts as arguments
- Fail without creating an `NDS` if any required system file doesn't load
- Add `UpdateConsole`, which delegates to `CreateConsole` if switching modes or starting the app
- Use `std::variant` to indicate whether a cart should be removed, inserted, or reused
- Load all system files (plus SD cards) in `UpdateConsole`
- Eject the cart and reinsert it into the new console if applicable
* Respect some more `Config` settings in the `Load*` functions
* Remove `InstallNAND` in favor of `LoadNAND`
* Fix some potential bugs in `LoadROMData`
* Oops, forgot to delete the definition of `InstallNAND`
* Add functions to get `FATStorageArgs`
- Not the cards themselves, but to get the arguments you _would_ use to load the cards
* Refactor `ROMManager::LoadROM`
- Load the ROM and save data before trying to initialize the console
* Clean up `ROMManager::Reset` and `BootToMenu`
- Let `EmuThread::UpdateConsole` do the heavy lifting
* Clean up `LoadGBAROM`
* Remove some unused functions
* Set the default DSi BIOS to be broken in `DSiArgs`
* Respect `Config::DSiFullBIOSBoot` when loading DSi BIOS files
* Remove some more unused functions
* Remove redundant `virtual` specifiers
* Refactor `NDSCart::CartCommon::Type()` to return a member instead of a constant
- One less virtual dispatch
- The cart type is read in `NDSCartSlot::DoSavestate`, which is a path downstream (due to rewinding)
* Remove a hash that I computed for debugging purposes
* Make `ByteSwap` `constexpr`
* Remove an unused `#include`
* Remove unnecessary functions from the NDS carts
- Mostly overrides that added nothing
* Default-initialize all NDSCart fields
* Make `GBACart::Type()` not rely on virtual dispatch
- `GBACartSlot::DoSavestate` calls it, and savestates can be a hot path downstream
* Don't forget to reset the base class in `CartGameSolarSensor::Reset()`
* Remove redundant `virtual` specifiers
* Default-initialize some fields in `GBACart`
* Fix ROMs not loading from archives in the frontend
- Whoops
* Change how the `Firmware` member is declared
* Forgot an include in Utils.cpp
* Rename `FirmwareMem::Firmware` to `FirmwareData` to fix a build error on Linux
- One of these days I'll convince you people to let me use `camelCaseMemberNames`
* Add `override` to places in `DSi_MMCStorage` that warrant it
* Fix firmware saving on the frontend
- Remove `GetConfigString` and `ConfigEntry::WifiSettingsPath` while I'm at it
* Add a non-const `GetNAND()`
2023-12-04 16:57:22 +00:00
|
|
|
#include "Args.h"
|
2020-06-30 21:50:41 +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"
|
2023-11-18 15:40:54 +00:00
|
|
|
#include "ARMJIT.h"
|
|
|
|
#include "ARMJIT_Memory.h"
|
2019-06-13 12:41:54 +00:00
|
|
|
|
2023-11-25 17:32:09 +00:00
|
|
|
namespace melonDS
|
|
|
|
{
|
2023-08-18 20:50:57 +00:00
|
|
|
using namespace Platform;
|
2018-12-11 14:56:34 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
const s32 kMaxIterationCycles = 64;
|
|
|
|
const s32 kIterationCycleMargin = 8;
|
2016-05-16 15:48:40 +00:00
|
|
|
|
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
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
NDS* NDS::Current = nullptr;
|
|
|
|
|
Refactor how save data (including SD cards) is initialized (#1898)
* Remove `FATStorage::Open` and `FATStorage::Close`
- That's what the constructor and destructor are for, respectively
* Add `FATStorage::IsReadOnly`
* Slight cleanup of `FATStorage`
- Make it move-constructible and move-assignable
- Represent the absence of a sync directory with `std::optional`, not an empty string
- Add `FATStorageArgs` for later use
* Refactor `CartHomebrew` to accept an optional `FATStorageArgs`
- `CartHomebrew` uses it to load an SD card image
- Not passing a `FATStorage` directly because we won't know if we need to load the card until we parse the ROM
- Store the `FATStorage` inside a `std::optional` instead of a pointer
- `CartHomebrew::Reset` no longer reloads the SD card; the frontend needs to set it with the `SetSDCard` method
* Close `NANDImage::CurFile` when move-assigning
- Whoops
* Add `Args.h`
- To construct a `NDS` or `DSi` with arguments
- Mostly intended for system files
* Fix incorrect `final` placement
* Refactor how `DSi`'s NAND and SD card are set
- Provide them via a `DSiArgs` argument in the constructor
- Give `DSi_MMCStorage` ownership of the `NANDImage` or `FATStorage` as needed, and expose getters/setters
- Replace `DSi_SDHost::Ports` with a `array<unique_ptr, 2>` to reduce the risk of leaks
- Store `DSi_MMCStorage`'s disk images in a `std::variant`
- The SD card and NAND image are no longer reset in `Reset()`; the frontend will need to do that itself
* Add getters/setters on `DSi` itself for its storage media
* Remove newly-unused `Platform::ConfigEntry`s
* Use `DSi::SetNAND` in the frontend
* Add `EmuThread::NeedToRecreateConsole`
* Document `NDSArgs` and give its fields default values
* Refactor how system files are loaded upon construction
- Pass `NDSArgs&&` into `NDS`'s constructor
- Use `std::array` for the emulator's BIOS images and the built-in FreeBIOS, to simplify copying and comparison
- Initialize the BIOS, firmware, and SD cards from `NDSArgs` or `DSiArgs`
- Add a new default constructor for `NDS` (not `DSi`) that initializes the DS with default system files
- Embed `FirmwareMem::Firmware` directly instead of in a `unique_ptr`
- `SPIHost` now takes a `Firmware&&` that it forwards to `FirmwareMem`
- Add `Firmware` getters/setters plus `const` variants for `NDS`, `Firmware`, and `FirmwareMem`
- Simplify installation of firmware
* Initialize the DSi BIOS in the constructor
- Change `DSi::ARM9iBIOS` and `ARM7iBIOS` to `std::array`
* Update the frontend to reflect the core's changes
* Remove `DSi_SDHost::CloseHandles`
* Pass `nullopt` instead of the empty string when folder sync is off
* Deduplicate ROM extraction logic
- `LoadGBAROM` and `LoadROM` now delegate to `LoadROMData`
- Also use `unique_ptr` instead of `new[]`
* Oops, missed some `get()`'s
* Move `NDS::IsLoadedARM9BIOSBuiltIn` to the header
- So it's likelier to be inlined
- Same for the ARM7 version
* Remove `NDS::SetConsoleType`
* Add `NDS::SetFirmware`
* Move `GBACart::SetupSave` to be `protected`
- It was only ever used inside the class
* Rename `GBACart::LoadSave` to `SetSaveMemory`
- Same for the cart slot
* Declare `GBACartSlot` as a friend of `GBACart::CartCommon`
* Revise `GBACartSlot`'s getters and setters
- Rename `InsertROM` and `LoadROM` to `SetCart`
- Add a `GetCart` method
* Clean up getters and setters for NDS and GBA carts
* Clean up how carts are inserted into the slots
- Remove setters that operate directly on pointers, to simplify error-handling (use ParseROM instead)
- Add overloads for all carts that accept a `const u8*` (to copy the ROM data) and a `unique_ptr<u8[]>` (to move the ROM data)
- Store all ROM and RAM data in `unique_ptr`
- Default-initialize all fields
- Simplify constructors and destructors, inheriting where applicable
* Refactor GBA save data insertion
- Make `SetupSave` private and non-virtual and move its logic to be in `SetSaveMemory`
- Add overloads for setting save data in the constructor
- Update the SRAM completely in `SetSaveMemory`
* Clean up `NDSCart::CartCommon::SetSaveMemory`
- Move its declaration next to the other `SaveMemory` methods
- Move its (empty) implementation to the header
* Add some comments
* Add Utils.cpp and Utils.h
* Rename some functions in Utils for clarity
* Add `GBACart::ParseROM` and `NDSCart::ParseROM` overloads that accept `unique_ptr<u8[]>`
- The `u8*` overloads delegate to these new overloads
- Also move `SetupSave` for both kinds of carts to be private non-virtual methods
* Finalize the `NDSCart` refactor
- Add `NDSCartArgs` to pass to `ParseROM`
- Add SRAM arguments for all retail carts
- Initialize SRAM inside the constructor
- Delegate to other constructors where possible
* Replace `ROMManager::NDSSave` and `GBASave` with `unique_ptr`
* Make both cart slots return the previously-inserted cart in `EjectCart`
- Primarily intended for reusing carts when resetting the console
* Make `NDS::EjectCart` return the old cart
* Initialize both cart slots with the provided ROM (if any)
* Make `NDS::EjectGBACart` return the ejected cart
* Clean up some comments in Args.h
* Rename `ROMManager::LoadBIOS` to `BootToMenu`
- Clarifies the intent
* Add `ROMManager::LoadDLDISDCard`
* Add a doc comment
* Refactor how the `NDS` is created or updated
- Rewrite `CreateConsole` to read from `Config` and load system files, but accept carts as arguments
- Fail without creating an `NDS` if any required system file doesn't load
- Add `UpdateConsole`, which delegates to `CreateConsole` if switching modes or starting the app
- Use `std::variant` to indicate whether a cart should be removed, inserted, or reused
- Load all system files (plus SD cards) in `UpdateConsole`
- Eject the cart and reinsert it into the new console if applicable
* Respect some more `Config` settings in the `Load*` functions
* Remove `InstallNAND` in favor of `LoadNAND`
* Fix some potential bugs in `LoadROMData`
* Oops, forgot to delete the definition of `InstallNAND`
* Add functions to get `FATStorageArgs`
- Not the cards themselves, but to get the arguments you _would_ use to load the cards
* Refactor `ROMManager::LoadROM`
- Load the ROM and save data before trying to initialize the console
* Clean up `ROMManager::Reset` and `BootToMenu`
- Let `EmuThread::UpdateConsole` do the heavy lifting
* Clean up `LoadGBAROM`
* Remove some unused functions
* Set the default DSi BIOS to be broken in `DSiArgs`
* Respect `Config::DSiFullBIOSBoot` when loading DSi BIOS files
* Remove some more unused functions
* Remove redundant `virtual` specifiers
* Refactor `NDSCart::CartCommon::Type()` to return a member instead of a constant
- One less virtual dispatch
- The cart type is read in `NDSCartSlot::DoSavestate`, which is a path downstream (due to rewinding)
* Remove a hash that I computed for debugging purposes
* Make `ByteSwap` `constexpr`
* Remove an unused `#include`
* Remove unnecessary functions from the NDS carts
- Mostly overrides that added nothing
* Default-initialize all NDSCart fields
* Make `GBACart::Type()` not rely on virtual dispatch
- `GBACartSlot::DoSavestate` calls it, and savestates can be a hot path downstream
* Don't forget to reset the base class in `CartGameSolarSensor::Reset()`
* Remove redundant `virtual` specifiers
* Default-initialize some fields in `GBACart`
* Fix ROMs not loading from archives in the frontend
- Whoops
* Change how the `Firmware` member is declared
* Forgot an include in Utils.cpp
* Rename `FirmwareMem::Firmware` to `FirmwareData` to fix a build error on Linux
- One of these days I'll convince you people to let me use `camelCaseMemberNames`
* Add `override` to places in `DSi_MMCStorage` that warrant it
* Fix firmware saving on the frontend
- Remove `GetConfigString` and `ConfigEntry::WifiSettingsPath` while I'm at it
* Add a non-const `GetNAND()`
2023-12-04 16:57:22 +00:00
|
|
|
NDS::NDS() noexcept :
|
|
|
|
NDS(
|
|
|
|
NDSArgs {
|
|
|
|
nullptr,
|
|
|
|
nullptr,
|
|
|
|
bios_arm9_bin,
|
|
|
|
bios_arm7_bin,
|
|
|
|
Firmware(0),
|
|
|
|
}
|
|
|
|
)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
NDS::NDS(NDSArgs&& args, int type) noexcept :
|
2023-11-28 22:16:41 +00:00
|
|
|
ConsoleType(type),
|
Refactor how save data (including SD cards) is initialized (#1898)
* Remove `FATStorage::Open` and `FATStorage::Close`
- That's what the constructor and destructor are for, respectively
* Add `FATStorage::IsReadOnly`
* Slight cleanup of `FATStorage`
- Make it move-constructible and move-assignable
- Represent the absence of a sync directory with `std::optional`, not an empty string
- Add `FATStorageArgs` for later use
* Refactor `CartHomebrew` to accept an optional `FATStorageArgs`
- `CartHomebrew` uses it to load an SD card image
- Not passing a `FATStorage` directly because we won't know if we need to load the card until we parse the ROM
- Store the `FATStorage` inside a `std::optional` instead of a pointer
- `CartHomebrew::Reset` no longer reloads the SD card; the frontend needs to set it with the `SetSDCard` method
* Close `NANDImage::CurFile` when move-assigning
- Whoops
* Add `Args.h`
- To construct a `NDS` or `DSi` with arguments
- Mostly intended for system files
* Fix incorrect `final` placement
* Refactor how `DSi`'s NAND and SD card are set
- Provide them via a `DSiArgs` argument in the constructor
- Give `DSi_MMCStorage` ownership of the `NANDImage` or `FATStorage` as needed, and expose getters/setters
- Replace `DSi_SDHost::Ports` with a `array<unique_ptr, 2>` to reduce the risk of leaks
- Store `DSi_MMCStorage`'s disk images in a `std::variant`
- The SD card and NAND image are no longer reset in `Reset()`; the frontend will need to do that itself
* Add getters/setters on `DSi` itself for its storage media
* Remove newly-unused `Platform::ConfigEntry`s
* Use `DSi::SetNAND` in the frontend
* Add `EmuThread::NeedToRecreateConsole`
* Document `NDSArgs` and give its fields default values
* Refactor how system files are loaded upon construction
- Pass `NDSArgs&&` into `NDS`'s constructor
- Use `std::array` for the emulator's BIOS images and the built-in FreeBIOS, to simplify copying and comparison
- Initialize the BIOS, firmware, and SD cards from `NDSArgs` or `DSiArgs`
- Add a new default constructor for `NDS` (not `DSi`) that initializes the DS with default system files
- Embed `FirmwareMem::Firmware` directly instead of in a `unique_ptr`
- `SPIHost` now takes a `Firmware&&` that it forwards to `FirmwareMem`
- Add `Firmware` getters/setters plus `const` variants for `NDS`, `Firmware`, and `FirmwareMem`
- Simplify installation of firmware
* Initialize the DSi BIOS in the constructor
- Change `DSi::ARM9iBIOS` and `ARM7iBIOS` to `std::array`
* Update the frontend to reflect the core's changes
* Remove `DSi_SDHost::CloseHandles`
* Pass `nullopt` instead of the empty string when folder sync is off
* Deduplicate ROM extraction logic
- `LoadGBAROM` and `LoadROM` now delegate to `LoadROMData`
- Also use `unique_ptr` instead of `new[]`
* Oops, missed some `get()`'s
* Move `NDS::IsLoadedARM9BIOSBuiltIn` to the header
- So it's likelier to be inlined
- Same for the ARM7 version
* Remove `NDS::SetConsoleType`
* Add `NDS::SetFirmware`
* Move `GBACart::SetupSave` to be `protected`
- It was only ever used inside the class
* Rename `GBACart::LoadSave` to `SetSaveMemory`
- Same for the cart slot
* Declare `GBACartSlot` as a friend of `GBACart::CartCommon`
* Revise `GBACartSlot`'s getters and setters
- Rename `InsertROM` and `LoadROM` to `SetCart`
- Add a `GetCart` method
* Clean up getters and setters for NDS and GBA carts
* Clean up how carts are inserted into the slots
- Remove setters that operate directly on pointers, to simplify error-handling (use ParseROM instead)
- Add overloads for all carts that accept a `const u8*` (to copy the ROM data) and a `unique_ptr<u8[]>` (to move the ROM data)
- Store all ROM and RAM data in `unique_ptr`
- Default-initialize all fields
- Simplify constructors and destructors, inheriting where applicable
* Refactor GBA save data insertion
- Make `SetupSave` private and non-virtual and move its logic to be in `SetSaveMemory`
- Add overloads for setting save data in the constructor
- Update the SRAM completely in `SetSaveMemory`
* Clean up `NDSCart::CartCommon::SetSaveMemory`
- Move its declaration next to the other `SaveMemory` methods
- Move its (empty) implementation to the header
* Add some comments
* Add Utils.cpp and Utils.h
* Rename some functions in Utils for clarity
* Add `GBACart::ParseROM` and `NDSCart::ParseROM` overloads that accept `unique_ptr<u8[]>`
- The `u8*` overloads delegate to these new overloads
- Also move `SetupSave` for both kinds of carts to be private non-virtual methods
* Finalize the `NDSCart` refactor
- Add `NDSCartArgs` to pass to `ParseROM`
- Add SRAM arguments for all retail carts
- Initialize SRAM inside the constructor
- Delegate to other constructors where possible
* Replace `ROMManager::NDSSave` and `GBASave` with `unique_ptr`
* Make both cart slots return the previously-inserted cart in `EjectCart`
- Primarily intended for reusing carts when resetting the console
* Make `NDS::EjectCart` return the old cart
* Initialize both cart slots with the provided ROM (if any)
* Make `NDS::EjectGBACart` return the ejected cart
* Clean up some comments in Args.h
* Rename `ROMManager::LoadBIOS` to `BootToMenu`
- Clarifies the intent
* Add `ROMManager::LoadDLDISDCard`
* Add a doc comment
* Refactor how the `NDS` is created or updated
- Rewrite `CreateConsole` to read from `Config` and load system files, but accept carts as arguments
- Fail without creating an `NDS` if any required system file doesn't load
- Add `UpdateConsole`, which delegates to `CreateConsole` if switching modes or starting the app
- Use `std::variant` to indicate whether a cart should be removed, inserted, or reused
- Load all system files (plus SD cards) in `UpdateConsole`
- Eject the cart and reinsert it into the new console if applicable
* Respect some more `Config` settings in the `Load*` functions
* Remove `InstallNAND` in favor of `LoadNAND`
* Fix some potential bugs in `LoadROMData`
* Oops, forgot to delete the definition of `InstallNAND`
* Add functions to get `FATStorageArgs`
- Not the cards themselves, but to get the arguments you _would_ use to load the cards
* Refactor `ROMManager::LoadROM`
- Load the ROM and save data before trying to initialize the console
* Clean up `ROMManager::Reset` and `BootToMenu`
- Let `EmuThread::UpdateConsole` do the heavy lifting
* Clean up `LoadGBAROM`
* Remove some unused functions
* Set the default DSi BIOS to be broken in `DSiArgs`
* Respect `Config::DSiFullBIOSBoot` when loading DSi BIOS files
* Remove some more unused functions
* Remove redundant `virtual` specifiers
* Refactor `NDSCart::CartCommon::Type()` to return a member instead of a constant
- One less virtual dispatch
- The cart type is read in `NDSCartSlot::DoSavestate`, which is a path downstream (due to rewinding)
* Remove a hash that I computed for debugging purposes
* Make `ByteSwap` `constexpr`
* Remove an unused `#include`
* Remove unnecessary functions from the NDS carts
- Mostly overrides that added nothing
* Default-initialize all NDSCart fields
* Make `GBACart::Type()` not rely on virtual dispatch
- `GBACartSlot::DoSavestate` calls it, and savestates can be a hot path downstream
* Don't forget to reset the base class in `CartGameSolarSensor::Reset()`
* Remove redundant `virtual` specifiers
* Default-initialize some fields in `GBACart`
* Fix ROMs not loading from archives in the frontend
- Whoops
* Change how the `Firmware` member is declared
* Forgot an include in Utils.cpp
* Rename `FirmwareMem::Firmware` to `FirmwareData` to fix a build error on Linux
- One of these days I'll convince you people to let me use `camelCaseMemberNames`
* Add `override` to places in `DSi_MMCStorage` that warrant it
* Fix firmware saving on the frontend
- Remove `GetConfigString` and `ConfigEntry::WifiSettingsPath` while I'm at it
* Add a non-const `GetNAND()`
2023-12-04 16:57:22 +00:00
|
|
|
ARM7BIOS(args.ARM7BIOS),
|
|
|
|
ARM9BIOS(args.ARM9BIOS),
|
2023-12-15 13:54:41 +00:00
|
|
|
ARM7BIOSNative(CRC32(ARM7BIOS.data(), ARM7BIOS.size()) == ARM7BIOSCRC32),
|
|
|
|
ARM9BIOSNative(CRC32(ARM9BIOS.data(), ARM9BIOS.size()) == ARM9BIOSCRC32),
|
2023-12-05 15:47:16 +00:00
|
|
|
JIT(*this, args.JIT),
|
|
|
|
SPU(*this, args.BitDepth, args.Interpolation),
|
2023-12-15 13:53:31 +00:00
|
|
|
GPU(*this, std::move(args.Renderer3D)),
|
Refactor how save data (including SD cards) is initialized (#1898)
* Remove `FATStorage::Open` and `FATStorage::Close`
- That's what the constructor and destructor are for, respectively
* Add `FATStorage::IsReadOnly`
* Slight cleanup of `FATStorage`
- Make it move-constructible and move-assignable
- Represent the absence of a sync directory with `std::optional`, not an empty string
- Add `FATStorageArgs` for later use
* Refactor `CartHomebrew` to accept an optional `FATStorageArgs`
- `CartHomebrew` uses it to load an SD card image
- Not passing a `FATStorage` directly because we won't know if we need to load the card until we parse the ROM
- Store the `FATStorage` inside a `std::optional` instead of a pointer
- `CartHomebrew::Reset` no longer reloads the SD card; the frontend needs to set it with the `SetSDCard` method
* Close `NANDImage::CurFile` when move-assigning
- Whoops
* Add `Args.h`
- To construct a `NDS` or `DSi` with arguments
- Mostly intended for system files
* Fix incorrect `final` placement
* Refactor how `DSi`'s NAND and SD card are set
- Provide them via a `DSiArgs` argument in the constructor
- Give `DSi_MMCStorage` ownership of the `NANDImage` or `FATStorage` as needed, and expose getters/setters
- Replace `DSi_SDHost::Ports` with a `array<unique_ptr, 2>` to reduce the risk of leaks
- Store `DSi_MMCStorage`'s disk images in a `std::variant`
- The SD card and NAND image are no longer reset in `Reset()`; the frontend will need to do that itself
* Add getters/setters on `DSi` itself for its storage media
* Remove newly-unused `Platform::ConfigEntry`s
* Use `DSi::SetNAND` in the frontend
* Add `EmuThread::NeedToRecreateConsole`
* Document `NDSArgs` and give its fields default values
* Refactor how system files are loaded upon construction
- Pass `NDSArgs&&` into `NDS`'s constructor
- Use `std::array` for the emulator's BIOS images and the built-in FreeBIOS, to simplify copying and comparison
- Initialize the BIOS, firmware, and SD cards from `NDSArgs` or `DSiArgs`
- Add a new default constructor for `NDS` (not `DSi`) that initializes the DS with default system files
- Embed `FirmwareMem::Firmware` directly instead of in a `unique_ptr`
- `SPIHost` now takes a `Firmware&&` that it forwards to `FirmwareMem`
- Add `Firmware` getters/setters plus `const` variants for `NDS`, `Firmware`, and `FirmwareMem`
- Simplify installation of firmware
* Initialize the DSi BIOS in the constructor
- Change `DSi::ARM9iBIOS` and `ARM7iBIOS` to `std::array`
* Update the frontend to reflect the core's changes
* Remove `DSi_SDHost::CloseHandles`
* Pass `nullopt` instead of the empty string when folder sync is off
* Deduplicate ROM extraction logic
- `LoadGBAROM` and `LoadROM` now delegate to `LoadROMData`
- Also use `unique_ptr` instead of `new[]`
* Oops, missed some `get()`'s
* Move `NDS::IsLoadedARM9BIOSBuiltIn` to the header
- So it's likelier to be inlined
- Same for the ARM7 version
* Remove `NDS::SetConsoleType`
* Add `NDS::SetFirmware`
* Move `GBACart::SetupSave` to be `protected`
- It was only ever used inside the class
* Rename `GBACart::LoadSave` to `SetSaveMemory`
- Same for the cart slot
* Declare `GBACartSlot` as a friend of `GBACart::CartCommon`
* Revise `GBACartSlot`'s getters and setters
- Rename `InsertROM` and `LoadROM` to `SetCart`
- Add a `GetCart` method
* Clean up getters and setters for NDS and GBA carts
* Clean up how carts are inserted into the slots
- Remove setters that operate directly on pointers, to simplify error-handling (use ParseROM instead)
- Add overloads for all carts that accept a `const u8*` (to copy the ROM data) and a `unique_ptr<u8[]>` (to move the ROM data)
- Store all ROM and RAM data in `unique_ptr`
- Default-initialize all fields
- Simplify constructors and destructors, inheriting where applicable
* Refactor GBA save data insertion
- Make `SetupSave` private and non-virtual and move its logic to be in `SetSaveMemory`
- Add overloads for setting save data in the constructor
- Update the SRAM completely in `SetSaveMemory`
* Clean up `NDSCart::CartCommon::SetSaveMemory`
- Move its declaration next to the other `SaveMemory` methods
- Move its (empty) implementation to the header
* Add some comments
* Add Utils.cpp and Utils.h
* Rename some functions in Utils for clarity
* Add `GBACart::ParseROM` and `NDSCart::ParseROM` overloads that accept `unique_ptr<u8[]>`
- The `u8*` overloads delegate to these new overloads
- Also move `SetupSave` for both kinds of carts to be private non-virtual methods
* Finalize the `NDSCart` refactor
- Add `NDSCartArgs` to pass to `ParseROM`
- Add SRAM arguments for all retail carts
- Initialize SRAM inside the constructor
- Delegate to other constructors where possible
* Replace `ROMManager::NDSSave` and `GBASave` with `unique_ptr`
* Make both cart slots return the previously-inserted cart in `EjectCart`
- Primarily intended for reusing carts when resetting the console
* Make `NDS::EjectCart` return the old cart
* Initialize both cart slots with the provided ROM (if any)
* Make `NDS::EjectGBACart` return the ejected cart
* Clean up some comments in Args.h
* Rename `ROMManager::LoadBIOS` to `BootToMenu`
- Clarifies the intent
* Add `ROMManager::LoadDLDISDCard`
* Add a doc comment
* Refactor how the `NDS` is created or updated
- Rewrite `CreateConsole` to read from `Config` and load system files, but accept carts as arguments
- Fail without creating an `NDS` if any required system file doesn't load
- Add `UpdateConsole`, which delegates to `CreateConsole` if switching modes or starting the app
- Use `std::variant` to indicate whether a cart should be removed, inserted, or reused
- Load all system files (plus SD cards) in `UpdateConsole`
- Eject the cart and reinsert it into the new console if applicable
* Respect some more `Config` settings in the `Load*` functions
* Remove `InstallNAND` in favor of `LoadNAND`
* Fix some potential bugs in `LoadROMData`
* Oops, forgot to delete the definition of `InstallNAND`
* Add functions to get `FATStorageArgs`
- Not the cards themselves, but to get the arguments you _would_ use to load the cards
* Refactor `ROMManager::LoadROM`
- Load the ROM and save data before trying to initialize the console
* Clean up `ROMManager::Reset` and `BootToMenu`
- Let `EmuThread::UpdateConsole` do the heavy lifting
* Clean up `LoadGBAROM`
* Remove some unused functions
* Set the default DSi BIOS to be broken in `DSiArgs`
* Respect `Config::DSiFullBIOSBoot` when loading DSi BIOS files
* Remove some more unused functions
* Remove redundant `virtual` specifiers
* Refactor `NDSCart::CartCommon::Type()` to return a member instead of a constant
- One less virtual dispatch
- The cart type is read in `NDSCartSlot::DoSavestate`, which is a path downstream (due to rewinding)
* Remove a hash that I computed for debugging purposes
* Make `ByteSwap` `constexpr`
* Remove an unused `#include`
* Remove unnecessary functions from the NDS carts
- Mostly overrides that added nothing
* Default-initialize all NDSCart fields
* Make `GBACart::Type()` not rely on virtual dispatch
- `GBACartSlot::DoSavestate` calls it, and savestates can be a hot path downstream
* Don't forget to reset the base class in `CartGameSolarSensor::Reset()`
* Remove redundant `virtual` specifiers
* Default-initialize some fields in `GBACart`
* Fix ROMs not loading from archives in the frontend
- Whoops
* Change how the `Firmware` member is declared
* Forgot an include in Utils.cpp
* Rename `FirmwareMem::Firmware` to `FirmwareData` to fix a build error on Linux
- One of these days I'll convince you people to let me use `camelCaseMemberNames`
* Add `override` to places in `DSi_MMCStorage` that warrant it
* Fix firmware saving on the frontend
- Remove `GetConfigString` and `ConfigEntry::WifiSettingsPath` while I'm at it
* Add a non-const `GetNAND()`
2023-12-04 16:57:22 +00:00
|
|
|
SPI(*this, std::move(args.Firmware)),
|
2023-11-28 22:16:41 +00:00
|
|
|
RTC(*this),
|
|
|
|
Wifi(*this),
|
Refactor how save data (including SD cards) is initialized (#1898)
* Remove `FATStorage::Open` and `FATStorage::Close`
- That's what the constructor and destructor are for, respectively
* Add `FATStorage::IsReadOnly`
* Slight cleanup of `FATStorage`
- Make it move-constructible and move-assignable
- Represent the absence of a sync directory with `std::optional`, not an empty string
- Add `FATStorageArgs` for later use
* Refactor `CartHomebrew` to accept an optional `FATStorageArgs`
- `CartHomebrew` uses it to load an SD card image
- Not passing a `FATStorage` directly because we won't know if we need to load the card until we parse the ROM
- Store the `FATStorage` inside a `std::optional` instead of a pointer
- `CartHomebrew::Reset` no longer reloads the SD card; the frontend needs to set it with the `SetSDCard` method
* Close `NANDImage::CurFile` when move-assigning
- Whoops
* Add `Args.h`
- To construct a `NDS` or `DSi` with arguments
- Mostly intended for system files
* Fix incorrect `final` placement
* Refactor how `DSi`'s NAND and SD card are set
- Provide them via a `DSiArgs` argument in the constructor
- Give `DSi_MMCStorage` ownership of the `NANDImage` or `FATStorage` as needed, and expose getters/setters
- Replace `DSi_SDHost::Ports` with a `array<unique_ptr, 2>` to reduce the risk of leaks
- Store `DSi_MMCStorage`'s disk images in a `std::variant`
- The SD card and NAND image are no longer reset in `Reset()`; the frontend will need to do that itself
* Add getters/setters on `DSi` itself for its storage media
* Remove newly-unused `Platform::ConfigEntry`s
* Use `DSi::SetNAND` in the frontend
* Add `EmuThread::NeedToRecreateConsole`
* Document `NDSArgs` and give its fields default values
* Refactor how system files are loaded upon construction
- Pass `NDSArgs&&` into `NDS`'s constructor
- Use `std::array` for the emulator's BIOS images and the built-in FreeBIOS, to simplify copying and comparison
- Initialize the BIOS, firmware, and SD cards from `NDSArgs` or `DSiArgs`
- Add a new default constructor for `NDS` (not `DSi`) that initializes the DS with default system files
- Embed `FirmwareMem::Firmware` directly instead of in a `unique_ptr`
- `SPIHost` now takes a `Firmware&&` that it forwards to `FirmwareMem`
- Add `Firmware` getters/setters plus `const` variants for `NDS`, `Firmware`, and `FirmwareMem`
- Simplify installation of firmware
* Initialize the DSi BIOS in the constructor
- Change `DSi::ARM9iBIOS` and `ARM7iBIOS` to `std::array`
* Update the frontend to reflect the core's changes
* Remove `DSi_SDHost::CloseHandles`
* Pass `nullopt` instead of the empty string when folder sync is off
* Deduplicate ROM extraction logic
- `LoadGBAROM` and `LoadROM` now delegate to `LoadROMData`
- Also use `unique_ptr` instead of `new[]`
* Oops, missed some `get()`'s
* Move `NDS::IsLoadedARM9BIOSBuiltIn` to the header
- So it's likelier to be inlined
- Same for the ARM7 version
* Remove `NDS::SetConsoleType`
* Add `NDS::SetFirmware`
* Move `GBACart::SetupSave` to be `protected`
- It was only ever used inside the class
* Rename `GBACart::LoadSave` to `SetSaveMemory`
- Same for the cart slot
* Declare `GBACartSlot` as a friend of `GBACart::CartCommon`
* Revise `GBACartSlot`'s getters and setters
- Rename `InsertROM` and `LoadROM` to `SetCart`
- Add a `GetCart` method
* Clean up getters and setters for NDS and GBA carts
* Clean up how carts are inserted into the slots
- Remove setters that operate directly on pointers, to simplify error-handling (use ParseROM instead)
- Add overloads for all carts that accept a `const u8*` (to copy the ROM data) and a `unique_ptr<u8[]>` (to move the ROM data)
- Store all ROM and RAM data in `unique_ptr`
- Default-initialize all fields
- Simplify constructors and destructors, inheriting where applicable
* Refactor GBA save data insertion
- Make `SetupSave` private and non-virtual and move its logic to be in `SetSaveMemory`
- Add overloads for setting save data in the constructor
- Update the SRAM completely in `SetSaveMemory`
* Clean up `NDSCart::CartCommon::SetSaveMemory`
- Move its declaration next to the other `SaveMemory` methods
- Move its (empty) implementation to the header
* Add some comments
* Add Utils.cpp and Utils.h
* Rename some functions in Utils for clarity
* Add `GBACart::ParseROM` and `NDSCart::ParseROM` overloads that accept `unique_ptr<u8[]>`
- The `u8*` overloads delegate to these new overloads
- Also move `SetupSave` for both kinds of carts to be private non-virtual methods
* Finalize the `NDSCart` refactor
- Add `NDSCartArgs` to pass to `ParseROM`
- Add SRAM arguments for all retail carts
- Initialize SRAM inside the constructor
- Delegate to other constructors where possible
* Replace `ROMManager::NDSSave` and `GBASave` with `unique_ptr`
* Make both cart slots return the previously-inserted cart in `EjectCart`
- Primarily intended for reusing carts when resetting the console
* Make `NDS::EjectCart` return the old cart
* Initialize both cart slots with the provided ROM (if any)
* Make `NDS::EjectGBACart` return the ejected cart
* Clean up some comments in Args.h
* Rename `ROMManager::LoadBIOS` to `BootToMenu`
- Clarifies the intent
* Add `ROMManager::LoadDLDISDCard`
* Add a doc comment
* Refactor how the `NDS` is created or updated
- Rewrite `CreateConsole` to read from `Config` and load system files, but accept carts as arguments
- Fail without creating an `NDS` if any required system file doesn't load
- Add `UpdateConsole`, which delegates to `CreateConsole` if switching modes or starting the app
- Use `std::variant` to indicate whether a cart should be removed, inserted, or reused
- Load all system files (plus SD cards) in `UpdateConsole`
- Eject the cart and reinsert it into the new console if applicable
* Respect some more `Config` settings in the `Load*` functions
* Remove `InstallNAND` in favor of `LoadNAND`
* Fix some potential bugs in `LoadROMData`
* Oops, forgot to delete the definition of `InstallNAND`
* Add functions to get `FATStorageArgs`
- Not the cards themselves, but to get the arguments you _would_ use to load the cards
* Refactor `ROMManager::LoadROM`
- Load the ROM and save data before trying to initialize the console
* Clean up `ROMManager::Reset` and `BootToMenu`
- Let `EmuThread::UpdateConsole` do the heavy lifting
* Clean up `LoadGBAROM`
* Remove some unused functions
* Set the default DSi BIOS to be broken in `DSiArgs`
* Respect `Config::DSiFullBIOSBoot` when loading DSi BIOS files
* Remove some more unused functions
* Remove redundant `virtual` specifiers
* Refactor `NDSCart::CartCommon::Type()` to return a member instead of a constant
- One less virtual dispatch
- The cart type is read in `NDSCartSlot::DoSavestate`, which is a path downstream (due to rewinding)
* Remove a hash that I computed for debugging purposes
* Make `ByteSwap` `constexpr`
* Remove an unused `#include`
* Remove unnecessary functions from the NDS carts
- Mostly overrides that added nothing
* Default-initialize all NDSCart fields
* Make `GBACart::Type()` not rely on virtual dispatch
- `GBACartSlot::DoSavestate` calls it, and savestates can be a hot path downstream
* Don't forget to reset the base class in `CartGameSolarSensor::Reset()`
* Remove redundant `virtual` specifiers
* Default-initialize some fields in `GBACart`
* Fix ROMs not loading from archives in the frontend
- Whoops
* Change how the `Firmware` member is declared
* Forgot an include in Utils.cpp
* Rename `FirmwareMem::Firmware` to `FirmwareData` to fix a build error on Linux
- One of these days I'll convince you people to let me use `camelCaseMemberNames`
* Add `override` to places in `DSi_MMCStorage` that warrant it
* Fix firmware saving on the frontend
- Remove `GetConfigString` and `ConfigEntry::WifiSettingsPath` while I'm at it
* Add a non-const `GetNAND()`
2023-12-04 16:57:22 +00:00
|
|
|
NDSCartSlot(*this, std::move(args.NDSROM)),
|
|
|
|
GBACartSlot(type == 1 ? nullptr : std::move(args.GBAROM)),
|
2023-11-28 22:16:41 +00:00
|
|
|
AREngine(*this),
|
2023-12-05 15:47:16 +00:00
|
|
|
ARM9(*this, args.GDB, args.JIT.has_value()),
|
|
|
|
ARM7(*this, args.GDB, args.JIT.has_value()),
|
2023-12-19 14:15:35 +00:00
|
|
|
EnableJIT(args.JIT.has_value()),
|
2023-11-28 22:16:41 +00:00
|
|
|
DMAs {
|
|
|
|
DMA(0, 0, *this),
|
|
|
|
DMA(0, 1, *this),
|
|
|
|
DMA(0, 2, *this),
|
|
|
|
DMA(0, 3, *this),
|
|
|
|
DMA(1, 0, *this),
|
|
|
|
DMA(1, 1, *this),
|
|
|
|
DMA(1, 2, *this),
|
|
|
|
DMA(1, 3, *this),
|
|
|
|
}
|
2016-05-16 15:48:40 +00:00
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
RegisterEventFunc(Event_Div, 0, MemberEventFunc(NDS, DivDone));
|
|
|
|
RegisterEventFunc(Event_Sqrt, 0, MemberEventFunc(NDS, SqrtDone));
|
2016-11-03 00:38:58 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
MainRAM = JIT.Memory.GetMainRAM();
|
|
|
|
SharedWRAM = JIT.Memory.GetSharedWRAM();
|
|
|
|
ARM7WRAM = JIT.Memory.GetARM7WRAM();
|
2017-02-07 21:23:46 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
NDS::~NDS() noexcept
|
2017-02-07 21:23:46 +00:00
|
|
|
{
|
2023-11-02 20:04:09 +00:00
|
|
|
UnregisterEventFunc(Event_Div, 0);
|
|
|
|
UnregisterEventFunc(Event_Sqrt, 0);
|
2023-11-28 22:16:41 +00:00
|
|
|
// The destructor for each component is automatically called by the compiler
|
2016-05-16 15:48:40 +00:00
|
|
|
}
|
|
|
|
|
2016-12-06 16:32:51 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::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
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
ARM9.UpdateRegionTimings(addrstart<<2, addrend<<2);
|
2018-12-08 21:33:41 +00:00
|
|
|
}
|
2018-12-07 13:20:38 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::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
|
|
|
|
2023-12-05 15:47:16 +00:00
|
|
|
#ifdef JIT_ENABLED
|
|
|
|
void NDS::SetJITArgs(std::optional<JITArgs> args) noexcept
|
|
|
|
{
|
|
|
|
if (args)
|
|
|
|
{ // If we want to turn the JIT on...
|
|
|
|
JIT.SetJITArgs(*args);
|
|
|
|
}
|
|
|
|
else if (args.has_value() != EnableJIT)
|
|
|
|
{ // Else if we want to turn the JIT off, and it wasn't already off...
|
|
|
|
JIT.ResetBlockCache();
|
|
|
|
}
|
|
|
|
|
|
|
|
EnableJIT = args.has_value();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::InitTimings()
|
2018-12-08 21:33:41 +00:00
|
|
|
{
|
|
|
|
// 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
|
|
|
}
|
|
|
|
|
2023-12-12 10:07:22 +00:00
|
|
|
bool NDS::NeedsDirectBoot() const
|
2022-01-07 13:00:43 +00:00
|
|
|
{
|
|
|
|
if (ConsoleType == 1)
|
|
|
|
{
|
|
|
|
// for now, DSi mode requires original BIOS/NAND
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-12-05 15:47:16 +00:00
|
|
|
// DSi/3DS firmwares aren't bootable, neither is the generated firmware
|
|
|
|
if (!SPI.GetFirmware().IsBootable())
|
2022-01-07 13:00:43 +00:00
|
|
|
return true;
|
|
|
|
|
2023-12-05 15:47:16 +00:00
|
|
|
// FreeBIOS requires direct boot (it can't boot firmware)
|
2023-12-15 13:54:41 +00:00
|
|
|
if (!IsLoadedARM9BIOSKnownNative() || !IsLoadedARM7BIOSKnownNative())
|
2022-01-07 13:00:43 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::SetupDirectBoot()
|
2017-02-01 20:35:00 +00:00
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
const NDSHeader& header = NDSCartSlot.GetCart()->GetHeader();
|
|
|
|
u32 cartid = NDSCartSlot.GetCart()->ID();
|
|
|
|
const u8* cartrom = NDSCartSlot.GetCart()->GetROM();
|
|
|
|
MapSharedWRAM(3);
|
2023-06-30 11:28:52 +00:00
|
|
|
|
2023-12-08 17:29:30 +00:00
|
|
|
// Copy the Nintendo logo from the NDS ROM header to the ARM9 BIOS if using FreeBIOS
|
|
|
|
// Games need this for DS<->GBA comm to work
|
2023-12-15 13:54:41 +00:00
|
|
|
if (!IsLoadedARM9BIOSKnownNative())
|
2023-12-08 17:29:30 +00:00
|
|
|
{
|
|
|
|
memcpy(ARM9BIOS.data() + 0x20, header.NintendoLogo, 0x9C);
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
// setup main RAM data
|
|
|
|
|
|
|
|
for (u32 i = 0; i < 0x170; i+=4)
|
2020-06-01 18:36:30 +00:00
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
u32 tmp = *(u32*)&cartrom[i];
|
|
|
|
NDS::ARM9Write32(0x027FFE00+i, tmp);
|
2020-06-01 18:36:30 +00:00
|
|
|
}
|
2022-10-28 19:31:51 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
NDS::ARM9Write32(0x027FF800, cartid);
|
|
|
|
NDS::ARM9Write32(0x027FF804, cartid);
|
|
|
|
NDS::ARM9Write16(0x027FF808, header.HeaderCRC16);
|
|
|
|
NDS::ARM9Write16(0x027FF80A, header.SecureAreaCRC16);
|
2022-10-28 19:31:51 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
NDS::ARM9Write16(0x027FF850, 0x5835);
|
2022-10-28 19:31:51 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
NDS::ARM9Write32(0x027FFC00, cartid);
|
|
|
|
NDS::ARM9Write32(0x027FFC04, cartid);
|
|
|
|
NDS::ARM9Write16(0x027FFC08, header.HeaderCRC16);
|
|
|
|
NDS::ARM9Write16(0x027FFC0A, header.SecureAreaCRC16);
|
2022-10-28 19:31:51 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
NDS::ARM9Write16(0x027FFC10, 0x5835);
|
|
|
|
NDS::ARM9Write16(0x027FFC30, 0xFFFF);
|
|
|
|
NDS::ARM9Write16(0x027FFC40, 0x0001);
|
2022-10-28 19:31:51 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
u32 arm9start = 0;
|
2022-10-28 19:31:51 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
// load the ARM9 secure area
|
|
|
|
if (header.ARM9ROMOffset >= 0x4000 && header.ARM9ROMOffset < 0x8000)
|
|
|
|
{
|
|
|
|
u8 securearea[0x800];
|
|
|
|
NDSCartSlot.DecryptSecureArea(securearea);
|
2016-12-06 16:32:51 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
for (u32 i = 0; i < 0x800; i+=4)
|
2021-08-30 18:26:49 +00:00
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
NDS::ARM9Write32(header.ARM9RAMAddress+i, *(u32*)&securearea[i]);
|
|
|
|
arm9start += 4;
|
2021-08-30 18:26:49 +00:00
|
|
|
}
|
2023-11-28 22:16:41 +00:00
|
|
|
}
|
2017-01-31 02:54:51 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
// CHECKME: firmware seems to load this in 0x200 byte chunks
|
2020-03-30 09:04:50 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
for (u32 i = arm9start; i < header.ARM9Size; i+=4)
|
|
|
|
{
|
|
|
|
u32 tmp = *(u32*)&cartrom[header.ARM9ROMOffset+i];
|
|
|
|
NDS::ARM9Write32(header.ARM9RAMAddress+i, tmp);
|
|
|
|
}
|
2020-03-30 09:04:50 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
for (u32 i = 0; i < header.ARM7Size; i+=4)
|
|
|
|
{
|
|
|
|
u32 tmp = *(u32*)&cartrom[header.ARM7ROMOffset+i];
|
|
|
|
NDS::ARM7Write32(header.ARM7RAMAddress+i, tmp);
|
2021-10-28 19:15:12 +00:00
|
|
|
}
|
2016-12-23 20:22:22 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
ARM7BIOSProt = 0x1204;
|
|
|
|
|
|
|
|
SPI.GetFirmwareMem()->SetupDirectBoot();
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
void NDS::SetupDirectBoot(const std::string& romname)
|
|
|
|
{
|
|
|
|
const NDSHeader& header = NDSCartSlot.GetCart()->GetHeader();
|
|
|
|
SetupDirectBoot();
|
|
|
|
|
|
|
|
NDSCartSlot.SetupDirectBoot(romname);
|
2022-01-07 13:00:43 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
ARM9.R[12] = header.ARM9EntryAddress;
|
|
|
|
ARM9.R[13] = 0x03002F7C;
|
|
|
|
ARM9.R[14] = header.ARM9EntryAddress;
|
|
|
|
ARM9.R_IRQ[0] = 0x03003F80;
|
|
|
|
ARM9.R_SVC[0] = 0x03003FC0;
|
2017-03-20 23:53:04 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
ARM7.R[12] = header.ARM7EntryAddress;
|
|
|
|
ARM7.R[13] = 0x0380FD80;
|
|
|
|
ARM7.R[14] = header.ARM7EntryAddress;
|
|
|
|
ARM7.R_IRQ[0] = 0x0380FF80;
|
|
|
|
ARM7.R_SVC[0] = 0x0380FFC0;
|
2017-03-20 23:53:04 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
ARM9.JumpTo(header.ARM9EntryAddress);
|
|
|
|
ARM7.JumpTo(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;
|
2023-11-28 22:16:41 +00:00
|
|
|
GPU.SetPowerCnt(PowerControl9);
|
2017-02-05 16:15:17 +00:00
|
|
|
|
2017-06-04 23:58:14 +00:00
|
|
|
// checkme
|
|
|
|
RCnt = 0x8000;
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.SetSPICnt(0x8000);
|
2018-04-26 22:20:18 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
SPU.SetBias(0x200);
|
2017-04-07 15:37:49 +00:00
|
|
|
|
2018-12-08 21:33:41 +00:00
|
|
|
SetWifiWaitCnt(0x0030);
|
2016-12-06 16:32:51 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::Reset()
|
2016-05-16 15:48:40 +00:00
|
|
|
{
|
2023-08-18 20:50:57 +00:00
|
|
|
Platform::FileHandle* f;
|
2017-01-18 00:33:06 +00:00
|
|
|
u32 i;
|
2016-05-16 15:48:40 +00:00
|
|
|
|
2020-02-24 17:31:44 +00:00
|
|
|
RunningGame = false;
|
2018-12-12 01:48:37 +00:00
|
|
|
LastSysClockCycles = 0;
|
|
|
|
|
2023-09-18 19:09:11 +00:00
|
|
|
// BIOS files are now loaded by the frontend
|
2020-07-23 10:59:19 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.Reset();
|
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
|
|
|
{
|
2023-09-18 19:09:11 +00:00
|
|
|
// BIOS files are now loaded by the frontend
|
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
|
2023-11-28 22:16:41 +00:00
|
|
|
ARM9.CP15Reset();
|
2019-07-21 21:56:24 +00:00
|
|
|
|
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
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
ARM9.Reset();
|
|
|
|
ARM7.Reset();
|
2016-11-24 17:31:49 +00:00
|
|
|
|
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
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
for (i = 0; i < 8; i++) DMAs[i].Reset();
|
2017-01-18 00:33:06 +00:00
|
|
|
memset(DMA9Fill, 0, 4*4);
|
|
|
|
|
2023-11-02 20:04:09 +00:00
|
|
|
for (i = 0; i < Event_MAX; i++)
|
|
|
|
{
|
|
|
|
SchedEvent& evt = SchedList[i];
|
|
|
|
|
|
|
|
evt.Timestamp = 0;
|
|
|
|
evt.FuncID = 0;
|
|
|
|
evt.Param = 0;
|
|
|
|
}
|
2017-01-31 02:54:51 +00:00
|
|
|
SchedListMask = 0;
|
2016-12-05 16:08:24 +00:00
|
|
|
|
2016-12-23 20:22:22 +00:00
|
|
|
KeyInput = 0x007F03FF;
|
2023-10-30 17:37:49 +00:00
|
|
|
KeyCnt[0] = 0;
|
|
|
|
KeyCnt[1] = 0;
|
2017-06-04 20:34:31 +00:00
|
|
|
RCnt = 0;
|
2016-12-23 20:22:22 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
GPU.Reset();
|
|
|
|
NDSCartSlot.Reset();
|
|
|
|
GBACartSlot.Reset();
|
|
|
|
SPU.Reset();
|
|
|
|
SPI.Reset();
|
|
|
|
RTC.Reset();
|
|
|
|
Wifi.Reset();
|
2017-03-19 18:07:39 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::Start()
|
2022-01-07 13:00:43 +00:00
|
|
|
{
|
|
|
|
Running = true;
|
|
|
|
}
|
|
|
|
|
2023-08-18 20:50:57 +00:00
|
|
|
static const char* StopReasonName(Platform::StopReason reason)
|
2017-09-21 01:59:12 +00:00
|
|
|
{
|
2023-08-18 20:50:57 +00:00
|
|
|
switch (reason)
|
|
|
|
{
|
|
|
|
case Platform::StopReason::External:
|
|
|
|
return "External";
|
|
|
|
case Platform::StopReason::PowerOff:
|
|
|
|
return "PowerOff";
|
|
|
|
case Platform::StopReason::GBAModeNotSupported:
|
|
|
|
return "GBAModeNotSupported";
|
|
|
|
case Platform::StopReason::BadExceptionRegion:
|
|
|
|
return "BadExceptionRegion";
|
|
|
|
default:
|
|
|
|
return "Unknown";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::Stop(Platform::StopReason reason)
|
2023-08-18 20:50:57 +00:00
|
|
|
{
|
|
|
|
Platform::LogLevel level;
|
|
|
|
switch (reason)
|
|
|
|
{
|
|
|
|
case Platform::StopReason::External:
|
|
|
|
case Platform::StopReason::PowerOff:
|
|
|
|
level = LogLevel::Info;
|
|
|
|
break;
|
|
|
|
case Platform::StopReason::GBAModeNotSupported:
|
|
|
|
case Platform::StopReason::BadExceptionRegion:
|
|
|
|
level = LogLevel::Error;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
level = LogLevel::Warn;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
Log(level, "Stopping emulated console (Reason: %s)\n", StopReasonName(reason));
|
2017-10-01 01:19:39 +00:00
|
|
|
Running = false;
|
2023-08-18 20:50:57 +00:00
|
|
|
Platform::SignalStop(reason);
|
2023-11-28 22:16:41 +00:00
|
|
|
GPU.Stop();
|
|
|
|
SPU.Stop();
|
2017-09-21 01:59:12 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
bool NDS::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)
|
2023-06-12 21:56:09 +00:00
|
|
|
{
|
|
|
|
Log(LogLevel::Error, "savestate: Expected console type %d, got console type %d. cannot load.\n", ConsoleType, console);
|
2022-01-07 13:00:43 +00:00
|
|
|
return false;
|
2023-06-12 21:56:09 +00:00
|
|
|
}
|
2022-01-07 13:00:43 +00:00
|
|
|
}
|
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));
|
|
|
|
|
2023-11-02 20:04:09 +00:00
|
|
|
for (int i = 0; i < Event_MAX; i++)
|
2023-06-12 21:56:09 +00:00
|
|
|
{
|
2023-11-02 20:04:09 +00:00
|
|
|
SchedEvent& evt = SchedList[i];
|
|
|
|
|
|
|
|
file->Var64(&evt.Timestamp);
|
|
|
|
file->Var32(&evt.FuncID);
|
|
|
|
file->Var32(&evt.Param);
|
2023-06-12 21:56:09 +00:00
|
|
|
}
|
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????
|
2023-10-30 17:37:49 +00:00
|
|
|
file->VarArray(KeyCnt, 2*sizeof(u16));
|
2018-09-15 01:41:09 +00:00
|
|
|
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++)
|
2023-11-28 22:16:41 +00:00
|
|
|
DMAs[i].DoSavestate(file);
|
2020-02-24 17:31:44 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
ARM9.DoSavestate(file);
|
|
|
|
ARM7.DoSavestate(file);
|
2018-09-15 01:29:36 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.DoSavestate(file);
|
2022-01-07 13:00:43 +00:00
|
|
|
if (ConsoleType == 0)
|
2023-11-28 22:16:41 +00:00
|
|
|
GBACartSlot.DoSavestate(file);
|
|
|
|
GPU.DoSavestate(file);
|
|
|
|
SPU.DoSavestate(file);
|
|
|
|
SPI.DoSavestate(file);
|
|
|
|
RTC.DoSavestate(file);
|
|
|
|
Wifi.DoSavestate(file);
|
2018-10-18 00:31:01 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
DoSavestateExtra(file); // Handles DSi state if applicable
|
2022-01-07 13:00:43 +00:00
|
|
|
|
2018-12-18 16:04:42 +00:00
|
|
|
if (!file->Saving)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
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
|
|
|
|
2023-11-28 22:16:41 +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)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.ResetBlockCache();
|
|
|
|
JIT.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
|
|
|
|
2023-06-12 21:56:09 +00:00
|
|
|
file->Finish();
|
|
|
|
|
2018-10-18 00:31:01 +00:00
|
|
|
return true;
|
2018-09-15 00:47:34 +00:00
|
|
|
}
|
|
|
|
|
Refactor how save data (including SD cards) is initialized (#1898)
* Remove `FATStorage::Open` and `FATStorage::Close`
- That's what the constructor and destructor are for, respectively
* Add `FATStorage::IsReadOnly`
* Slight cleanup of `FATStorage`
- Make it move-constructible and move-assignable
- Represent the absence of a sync directory with `std::optional`, not an empty string
- Add `FATStorageArgs` for later use
* Refactor `CartHomebrew` to accept an optional `FATStorageArgs`
- `CartHomebrew` uses it to load an SD card image
- Not passing a `FATStorage` directly because we won't know if we need to load the card until we parse the ROM
- Store the `FATStorage` inside a `std::optional` instead of a pointer
- `CartHomebrew::Reset` no longer reloads the SD card; the frontend needs to set it with the `SetSDCard` method
* Close `NANDImage::CurFile` when move-assigning
- Whoops
* Add `Args.h`
- To construct a `NDS` or `DSi` with arguments
- Mostly intended for system files
* Fix incorrect `final` placement
* Refactor how `DSi`'s NAND and SD card are set
- Provide them via a `DSiArgs` argument in the constructor
- Give `DSi_MMCStorage` ownership of the `NANDImage` or `FATStorage` as needed, and expose getters/setters
- Replace `DSi_SDHost::Ports` with a `array<unique_ptr, 2>` to reduce the risk of leaks
- Store `DSi_MMCStorage`'s disk images in a `std::variant`
- The SD card and NAND image are no longer reset in `Reset()`; the frontend will need to do that itself
* Add getters/setters on `DSi` itself for its storage media
* Remove newly-unused `Platform::ConfigEntry`s
* Use `DSi::SetNAND` in the frontend
* Add `EmuThread::NeedToRecreateConsole`
* Document `NDSArgs` and give its fields default values
* Refactor how system files are loaded upon construction
- Pass `NDSArgs&&` into `NDS`'s constructor
- Use `std::array` for the emulator's BIOS images and the built-in FreeBIOS, to simplify copying and comparison
- Initialize the BIOS, firmware, and SD cards from `NDSArgs` or `DSiArgs`
- Add a new default constructor for `NDS` (not `DSi`) that initializes the DS with default system files
- Embed `FirmwareMem::Firmware` directly instead of in a `unique_ptr`
- `SPIHost` now takes a `Firmware&&` that it forwards to `FirmwareMem`
- Add `Firmware` getters/setters plus `const` variants for `NDS`, `Firmware`, and `FirmwareMem`
- Simplify installation of firmware
* Initialize the DSi BIOS in the constructor
- Change `DSi::ARM9iBIOS` and `ARM7iBIOS` to `std::array`
* Update the frontend to reflect the core's changes
* Remove `DSi_SDHost::CloseHandles`
* Pass `nullopt` instead of the empty string when folder sync is off
* Deduplicate ROM extraction logic
- `LoadGBAROM` and `LoadROM` now delegate to `LoadROMData`
- Also use `unique_ptr` instead of `new[]`
* Oops, missed some `get()`'s
* Move `NDS::IsLoadedARM9BIOSBuiltIn` to the header
- So it's likelier to be inlined
- Same for the ARM7 version
* Remove `NDS::SetConsoleType`
* Add `NDS::SetFirmware`
* Move `GBACart::SetupSave` to be `protected`
- It was only ever used inside the class
* Rename `GBACart::LoadSave` to `SetSaveMemory`
- Same for the cart slot
* Declare `GBACartSlot` as a friend of `GBACart::CartCommon`
* Revise `GBACartSlot`'s getters and setters
- Rename `InsertROM` and `LoadROM` to `SetCart`
- Add a `GetCart` method
* Clean up getters and setters for NDS and GBA carts
* Clean up how carts are inserted into the slots
- Remove setters that operate directly on pointers, to simplify error-handling (use ParseROM instead)
- Add overloads for all carts that accept a `const u8*` (to copy the ROM data) and a `unique_ptr<u8[]>` (to move the ROM data)
- Store all ROM and RAM data in `unique_ptr`
- Default-initialize all fields
- Simplify constructors and destructors, inheriting where applicable
* Refactor GBA save data insertion
- Make `SetupSave` private and non-virtual and move its logic to be in `SetSaveMemory`
- Add overloads for setting save data in the constructor
- Update the SRAM completely in `SetSaveMemory`
* Clean up `NDSCart::CartCommon::SetSaveMemory`
- Move its declaration next to the other `SaveMemory` methods
- Move its (empty) implementation to the header
* Add some comments
* Add Utils.cpp and Utils.h
* Rename some functions in Utils for clarity
* Add `GBACart::ParseROM` and `NDSCart::ParseROM` overloads that accept `unique_ptr<u8[]>`
- The `u8*` overloads delegate to these new overloads
- Also move `SetupSave` for both kinds of carts to be private non-virtual methods
* Finalize the `NDSCart` refactor
- Add `NDSCartArgs` to pass to `ParseROM`
- Add SRAM arguments for all retail carts
- Initialize SRAM inside the constructor
- Delegate to other constructors where possible
* Replace `ROMManager::NDSSave` and `GBASave` with `unique_ptr`
* Make both cart slots return the previously-inserted cart in `EjectCart`
- Primarily intended for reusing carts when resetting the console
* Make `NDS::EjectCart` return the old cart
* Initialize both cart slots with the provided ROM (if any)
* Make `NDS::EjectGBACart` return the ejected cart
* Clean up some comments in Args.h
* Rename `ROMManager::LoadBIOS` to `BootToMenu`
- Clarifies the intent
* Add `ROMManager::LoadDLDISDCard`
* Add a doc comment
* Refactor how the `NDS` is created or updated
- Rewrite `CreateConsole` to read from `Config` and load system files, but accept carts as arguments
- Fail without creating an `NDS` if any required system file doesn't load
- Add `UpdateConsole`, which delegates to `CreateConsole` if switching modes or starting the app
- Use `std::variant` to indicate whether a cart should be removed, inserted, or reused
- Load all system files (plus SD cards) in `UpdateConsole`
- Eject the cart and reinsert it into the new console if applicable
* Respect some more `Config` settings in the `Load*` functions
* Remove `InstallNAND` in favor of `LoadNAND`
* Fix some potential bugs in `LoadROMData`
* Oops, forgot to delete the definition of `InstallNAND`
* Add functions to get `FATStorageArgs`
- Not the cards themselves, but to get the arguments you _would_ use to load the cards
* Refactor `ROMManager::LoadROM`
- Load the ROM and save data before trying to initialize the console
* Clean up `ROMManager::Reset` and `BootToMenu`
- Let `EmuThread::UpdateConsole` do the heavy lifting
* Clean up `LoadGBAROM`
* Remove some unused functions
* Set the default DSi BIOS to be broken in `DSiArgs`
* Respect `Config::DSiFullBIOSBoot` when loading DSi BIOS files
* Remove some more unused functions
* Remove redundant `virtual` specifiers
* Refactor `NDSCart::CartCommon::Type()` to return a member instead of a constant
- One less virtual dispatch
- The cart type is read in `NDSCartSlot::DoSavestate`, which is a path downstream (due to rewinding)
* Remove a hash that I computed for debugging purposes
* Make `ByteSwap` `constexpr`
* Remove an unused `#include`
* Remove unnecessary functions from the NDS carts
- Mostly overrides that added nothing
* Default-initialize all NDSCart fields
* Make `GBACart::Type()` not rely on virtual dispatch
- `GBACartSlot::DoSavestate` calls it, and savestates can be a hot path downstream
* Don't forget to reset the base class in `CartGameSolarSensor::Reset()`
* Remove redundant `virtual` specifiers
* Default-initialize some fields in `GBACart`
* Fix ROMs not loading from archives in the frontend
- Whoops
* Change how the `Firmware` member is declared
* Forgot an include in Utils.cpp
* Rename `FirmwareMem::Firmware` to `FirmwareData` to fix a build error on Linux
- One of these days I'll convince you people to let me use `camelCaseMemberNames`
* Add `override` to places in `DSi_MMCStorage` that warrant it
* Fix firmware saving on the frontend
- Remove `GetConfigString` and `ConfigEntry::WifiSettingsPath` while I'm at it
* Add a non-const `GetNAND()`
2023-12-04 16:57:22 +00:00
|
|
|
void NDS::SetNDSCart(std::unique_ptr<NDSCart::CartCommon>&& cart)
|
2020-06-01 18:36:30 +00:00
|
|
|
{
|
Refactor how save data (including SD cards) is initialized (#1898)
* Remove `FATStorage::Open` and `FATStorage::Close`
- That's what the constructor and destructor are for, respectively
* Add `FATStorage::IsReadOnly`
* Slight cleanup of `FATStorage`
- Make it move-constructible and move-assignable
- Represent the absence of a sync directory with `std::optional`, not an empty string
- Add `FATStorageArgs` for later use
* Refactor `CartHomebrew` to accept an optional `FATStorageArgs`
- `CartHomebrew` uses it to load an SD card image
- Not passing a `FATStorage` directly because we won't know if we need to load the card until we parse the ROM
- Store the `FATStorage` inside a `std::optional` instead of a pointer
- `CartHomebrew::Reset` no longer reloads the SD card; the frontend needs to set it with the `SetSDCard` method
* Close `NANDImage::CurFile` when move-assigning
- Whoops
* Add `Args.h`
- To construct a `NDS` or `DSi` with arguments
- Mostly intended for system files
* Fix incorrect `final` placement
* Refactor how `DSi`'s NAND and SD card are set
- Provide them via a `DSiArgs` argument in the constructor
- Give `DSi_MMCStorage` ownership of the `NANDImage` or `FATStorage` as needed, and expose getters/setters
- Replace `DSi_SDHost::Ports` with a `array<unique_ptr, 2>` to reduce the risk of leaks
- Store `DSi_MMCStorage`'s disk images in a `std::variant`
- The SD card and NAND image are no longer reset in `Reset()`; the frontend will need to do that itself
* Add getters/setters on `DSi` itself for its storage media
* Remove newly-unused `Platform::ConfigEntry`s
* Use `DSi::SetNAND` in the frontend
* Add `EmuThread::NeedToRecreateConsole`
* Document `NDSArgs` and give its fields default values
* Refactor how system files are loaded upon construction
- Pass `NDSArgs&&` into `NDS`'s constructor
- Use `std::array` for the emulator's BIOS images and the built-in FreeBIOS, to simplify copying and comparison
- Initialize the BIOS, firmware, and SD cards from `NDSArgs` or `DSiArgs`
- Add a new default constructor for `NDS` (not `DSi`) that initializes the DS with default system files
- Embed `FirmwareMem::Firmware` directly instead of in a `unique_ptr`
- `SPIHost` now takes a `Firmware&&` that it forwards to `FirmwareMem`
- Add `Firmware` getters/setters plus `const` variants for `NDS`, `Firmware`, and `FirmwareMem`
- Simplify installation of firmware
* Initialize the DSi BIOS in the constructor
- Change `DSi::ARM9iBIOS` and `ARM7iBIOS` to `std::array`
* Update the frontend to reflect the core's changes
* Remove `DSi_SDHost::CloseHandles`
* Pass `nullopt` instead of the empty string when folder sync is off
* Deduplicate ROM extraction logic
- `LoadGBAROM` and `LoadROM` now delegate to `LoadROMData`
- Also use `unique_ptr` instead of `new[]`
* Oops, missed some `get()`'s
* Move `NDS::IsLoadedARM9BIOSBuiltIn` to the header
- So it's likelier to be inlined
- Same for the ARM7 version
* Remove `NDS::SetConsoleType`
* Add `NDS::SetFirmware`
* Move `GBACart::SetupSave` to be `protected`
- It was only ever used inside the class
* Rename `GBACart::LoadSave` to `SetSaveMemory`
- Same for the cart slot
* Declare `GBACartSlot` as a friend of `GBACart::CartCommon`
* Revise `GBACartSlot`'s getters and setters
- Rename `InsertROM` and `LoadROM` to `SetCart`
- Add a `GetCart` method
* Clean up getters and setters for NDS and GBA carts
* Clean up how carts are inserted into the slots
- Remove setters that operate directly on pointers, to simplify error-handling (use ParseROM instead)
- Add overloads for all carts that accept a `const u8*` (to copy the ROM data) and a `unique_ptr<u8[]>` (to move the ROM data)
- Store all ROM and RAM data in `unique_ptr`
- Default-initialize all fields
- Simplify constructors and destructors, inheriting where applicable
* Refactor GBA save data insertion
- Make `SetupSave` private and non-virtual and move its logic to be in `SetSaveMemory`
- Add overloads for setting save data in the constructor
- Update the SRAM completely in `SetSaveMemory`
* Clean up `NDSCart::CartCommon::SetSaveMemory`
- Move its declaration next to the other `SaveMemory` methods
- Move its (empty) implementation to the header
* Add some comments
* Add Utils.cpp and Utils.h
* Rename some functions in Utils for clarity
* Add `GBACart::ParseROM` and `NDSCart::ParseROM` overloads that accept `unique_ptr<u8[]>`
- The `u8*` overloads delegate to these new overloads
- Also move `SetupSave` for both kinds of carts to be private non-virtual methods
* Finalize the `NDSCart` refactor
- Add `NDSCartArgs` to pass to `ParseROM`
- Add SRAM arguments for all retail carts
- Initialize SRAM inside the constructor
- Delegate to other constructors where possible
* Replace `ROMManager::NDSSave` and `GBASave` with `unique_ptr`
* Make both cart slots return the previously-inserted cart in `EjectCart`
- Primarily intended for reusing carts when resetting the console
* Make `NDS::EjectCart` return the old cart
* Initialize both cart slots with the provided ROM (if any)
* Make `NDS::EjectGBACart` return the ejected cart
* Clean up some comments in Args.h
* Rename `ROMManager::LoadBIOS` to `BootToMenu`
- Clarifies the intent
* Add `ROMManager::LoadDLDISDCard`
* Add a doc comment
* Refactor how the `NDS` is created or updated
- Rewrite `CreateConsole` to read from `Config` and load system files, but accept carts as arguments
- Fail without creating an `NDS` if any required system file doesn't load
- Add `UpdateConsole`, which delegates to `CreateConsole` if switching modes or starting the app
- Use `std::variant` to indicate whether a cart should be removed, inserted, or reused
- Load all system files (plus SD cards) in `UpdateConsole`
- Eject the cart and reinsert it into the new console if applicable
* Respect some more `Config` settings in the `Load*` functions
* Remove `InstallNAND` in favor of `LoadNAND`
* Fix some potential bugs in `LoadROMData`
* Oops, forgot to delete the definition of `InstallNAND`
* Add functions to get `FATStorageArgs`
- Not the cards themselves, but to get the arguments you _would_ use to load the cards
* Refactor `ROMManager::LoadROM`
- Load the ROM and save data before trying to initialize the console
* Clean up `ROMManager::Reset` and `BootToMenu`
- Let `EmuThread::UpdateConsole` do the heavy lifting
* Clean up `LoadGBAROM`
* Remove some unused functions
* Set the default DSi BIOS to be broken in `DSiArgs`
* Respect `Config::DSiFullBIOSBoot` when loading DSi BIOS files
* Remove some more unused functions
* Remove redundant `virtual` specifiers
* Refactor `NDSCart::CartCommon::Type()` to return a member instead of a constant
- One less virtual dispatch
- The cart type is read in `NDSCartSlot::DoSavestate`, which is a path downstream (due to rewinding)
* Remove a hash that I computed for debugging purposes
* Make `ByteSwap` `constexpr`
* Remove an unused `#include`
* Remove unnecessary functions from the NDS carts
- Mostly overrides that added nothing
* Default-initialize all NDSCart fields
* Make `GBACart::Type()` not rely on virtual dispatch
- `GBACartSlot::DoSavestate` calls it, and savestates can be a hot path downstream
* Don't forget to reset the base class in `CartGameSolarSensor::Reset()`
* Remove redundant `virtual` specifiers
* Default-initialize some fields in `GBACart`
* Fix ROMs not loading from archives in the frontend
- Whoops
* Change how the `Firmware` member is declared
* Forgot an include in Utils.cpp
* Rename `FirmwareMem::Firmware` to `FirmwareData` to fix a build error on Linux
- One of these days I'll convince you people to let me use `camelCaseMemberNames`
* Add `override` to places in `DSi_MMCStorage` that warrant it
* Fix firmware saving on the frontend
- Remove `GetConfigString` and `ConfigEntry::WifiSettingsPath` while I'm at it
* Add a non-const `GetNAND()`
2023-12-04 16:57:22 +00:00
|
|
|
NDSCartSlot.SetCart(std::move(cart));
|
|
|
|
// The existing cart will always be ejected;
|
|
|
|
// if cart is null, then that's equivalent to ejecting a cart
|
|
|
|
// without inserting a new one.
|
2021-01-22 10:22:32 +00:00
|
|
|
}
|
|
|
|
|
Refactor how save data (including SD cards) is initialized (#1898)
* Remove `FATStorage::Open` and `FATStorage::Close`
- That's what the constructor and destructor are for, respectively
* Add `FATStorage::IsReadOnly`
* Slight cleanup of `FATStorage`
- Make it move-constructible and move-assignable
- Represent the absence of a sync directory with `std::optional`, not an empty string
- Add `FATStorageArgs` for later use
* Refactor `CartHomebrew` to accept an optional `FATStorageArgs`
- `CartHomebrew` uses it to load an SD card image
- Not passing a `FATStorage` directly because we won't know if we need to load the card until we parse the ROM
- Store the `FATStorage` inside a `std::optional` instead of a pointer
- `CartHomebrew::Reset` no longer reloads the SD card; the frontend needs to set it with the `SetSDCard` method
* Close `NANDImage::CurFile` when move-assigning
- Whoops
* Add `Args.h`
- To construct a `NDS` or `DSi` with arguments
- Mostly intended for system files
* Fix incorrect `final` placement
* Refactor how `DSi`'s NAND and SD card are set
- Provide them via a `DSiArgs` argument in the constructor
- Give `DSi_MMCStorage` ownership of the `NANDImage` or `FATStorage` as needed, and expose getters/setters
- Replace `DSi_SDHost::Ports` with a `array<unique_ptr, 2>` to reduce the risk of leaks
- Store `DSi_MMCStorage`'s disk images in a `std::variant`
- The SD card and NAND image are no longer reset in `Reset()`; the frontend will need to do that itself
* Add getters/setters on `DSi` itself for its storage media
* Remove newly-unused `Platform::ConfigEntry`s
* Use `DSi::SetNAND` in the frontend
* Add `EmuThread::NeedToRecreateConsole`
* Document `NDSArgs` and give its fields default values
* Refactor how system files are loaded upon construction
- Pass `NDSArgs&&` into `NDS`'s constructor
- Use `std::array` for the emulator's BIOS images and the built-in FreeBIOS, to simplify copying and comparison
- Initialize the BIOS, firmware, and SD cards from `NDSArgs` or `DSiArgs`
- Add a new default constructor for `NDS` (not `DSi`) that initializes the DS with default system files
- Embed `FirmwareMem::Firmware` directly instead of in a `unique_ptr`
- `SPIHost` now takes a `Firmware&&` that it forwards to `FirmwareMem`
- Add `Firmware` getters/setters plus `const` variants for `NDS`, `Firmware`, and `FirmwareMem`
- Simplify installation of firmware
* Initialize the DSi BIOS in the constructor
- Change `DSi::ARM9iBIOS` and `ARM7iBIOS` to `std::array`
* Update the frontend to reflect the core's changes
* Remove `DSi_SDHost::CloseHandles`
* Pass `nullopt` instead of the empty string when folder sync is off
* Deduplicate ROM extraction logic
- `LoadGBAROM` and `LoadROM` now delegate to `LoadROMData`
- Also use `unique_ptr` instead of `new[]`
* Oops, missed some `get()`'s
* Move `NDS::IsLoadedARM9BIOSBuiltIn` to the header
- So it's likelier to be inlined
- Same for the ARM7 version
* Remove `NDS::SetConsoleType`
* Add `NDS::SetFirmware`
* Move `GBACart::SetupSave` to be `protected`
- It was only ever used inside the class
* Rename `GBACart::LoadSave` to `SetSaveMemory`
- Same for the cart slot
* Declare `GBACartSlot` as a friend of `GBACart::CartCommon`
* Revise `GBACartSlot`'s getters and setters
- Rename `InsertROM` and `LoadROM` to `SetCart`
- Add a `GetCart` method
* Clean up getters and setters for NDS and GBA carts
* Clean up how carts are inserted into the slots
- Remove setters that operate directly on pointers, to simplify error-handling (use ParseROM instead)
- Add overloads for all carts that accept a `const u8*` (to copy the ROM data) and a `unique_ptr<u8[]>` (to move the ROM data)
- Store all ROM and RAM data in `unique_ptr`
- Default-initialize all fields
- Simplify constructors and destructors, inheriting where applicable
* Refactor GBA save data insertion
- Make `SetupSave` private and non-virtual and move its logic to be in `SetSaveMemory`
- Add overloads for setting save data in the constructor
- Update the SRAM completely in `SetSaveMemory`
* Clean up `NDSCart::CartCommon::SetSaveMemory`
- Move its declaration next to the other `SaveMemory` methods
- Move its (empty) implementation to the header
* Add some comments
* Add Utils.cpp and Utils.h
* Rename some functions in Utils for clarity
* Add `GBACart::ParseROM` and `NDSCart::ParseROM` overloads that accept `unique_ptr<u8[]>`
- The `u8*` overloads delegate to these new overloads
- Also move `SetupSave` for both kinds of carts to be private non-virtual methods
* Finalize the `NDSCart` refactor
- Add `NDSCartArgs` to pass to `ParseROM`
- Add SRAM arguments for all retail carts
- Initialize SRAM inside the constructor
- Delegate to other constructors where possible
* Replace `ROMManager::NDSSave` and `GBASave` with `unique_ptr`
* Make both cart slots return the previously-inserted cart in `EjectCart`
- Primarily intended for reusing carts when resetting the console
* Make `NDS::EjectCart` return the old cart
* Initialize both cart slots with the provided ROM (if any)
* Make `NDS::EjectGBACart` return the ejected cart
* Clean up some comments in Args.h
* Rename `ROMManager::LoadBIOS` to `BootToMenu`
- Clarifies the intent
* Add `ROMManager::LoadDLDISDCard`
* Add a doc comment
* Refactor how the `NDS` is created or updated
- Rewrite `CreateConsole` to read from `Config` and load system files, but accept carts as arguments
- Fail without creating an `NDS` if any required system file doesn't load
- Add `UpdateConsole`, which delegates to `CreateConsole` if switching modes or starting the app
- Use `std::variant` to indicate whether a cart should be removed, inserted, or reused
- Load all system files (plus SD cards) in `UpdateConsole`
- Eject the cart and reinsert it into the new console if applicable
* Respect some more `Config` settings in the `Load*` functions
* Remove `InstallNAND` in favor of `LoadNAND`
* Fix some potential bugs in `LoadROMData`
* Oops, forgot to delete the definition of `InstallNAND`
* Add functions to get `FATStorageArgs`
- Not the cards themselves, but to get the arguments you _would_ use to load the cards
* Refactor `ROMManager::LoadROM`
- Load the ROM and save data before trying to initialize the console
* Clean up `ROMManager::Reset` and `BootToMenu`
- Let `EmuThread::UpdateConsole` do the heavy lifting
* Clean up `LoadGBAROM`
* Remove some unused functions
* Set the default DSi BIOS to be broken in `DSiArgs`
* Respect `Config::DSiFullBIOSBoot` when loading DSi BIOS files
* Remove some more unused functions
* Remove redundant `virtual` specifiers
* Refactor `NDSCart::CartCommon::Type()` to return a member instead of a constant
- One less virtual dispatch
- The cart type is read in `NDSCartSlot::DoSavestate`, which is a path downstream (due to rewinding)
* Remove a hash that I computed for debugging purposes
* Make `ByteSwap` `constexpr`
* Remove an unused `#include`
* Remove unnecessary functions from the NDS carts
- Mostly overrides that added nothing
* Default-initialize all NDSCart fields
* Make `GBACart::Type()` not rely on virtual dispatch
- `GBACartSlot::DoSavestate` calls it, and savestates can be a hot path downstream
* Don't forget to reset the base class in `CartGameSolarSensor::Reset()`
* Remove redundant `virtual` specifiers
* Default-initialize some fields in `GBACart`
* Fix ROMs not loading from archives in the frontend
- Whoops
* Change how the `Firmware` member is declared
* Forgot an include in Utils.cpp
* Rename `FirmwareMem::Firmware` to `FirmwareData` to fix a build error on Linux
- One of these days I'll convince you people to let me use `camelCaseMemberNames`
* Add `override` to places in `DSi_MMCStorage` that warrant it
* Fix firmware saving on the frontend
- Remove `GetConfigString` and `ConfigEntry::WifiSettingsPath` while I'm at it
* Add a non-const `GetNAND()`
2023-12-04 16:57:22 +00:00
|
|
|
void NDS::SetNDSSave(const u8* savedata, u32 savelen)
|
2017-03-19 18:07:39 +00:00
|
|
|
{
|
2022-01-07 13:00:43 +00:00
|
|
|
if (savedata && savelen)
|
Refactor how save data (including SD cards) is initialized (#1898)
* Remove `FATStorage::Open` and `FATStorage::Close`
- That's what the constructor and destructor are for, respectively
* Add `FATStorage::IsReadOnly`
* Slight cleanup of `FATStorage`
- Make it move-constructible and move-assignable
- Represent the absence of a sync directory with `std::optional`, not an empty string
- Add `FATStorageArgs` for later use
* Refactor `CartHomebrew` to accept an optional `FATStorageArgs`
- `CartHomebrew` uses it to load an SD card image
- Not passing a `FATStorage` directly because we won't know if we need to load the card until we parse the ROM
- Store the `FATStorage` inside a `std::optional` instead of a pointer
- `CartHomebrew::Reset` no longer reloads the SD card; the frontend needs to set it with the `SetSDCard` method
* Close `NANDImage::CurFile` when move-assigning
- Whoops
* Add `Args.h`
- To construct a `NDS` or `DSi` with arguments
- Mostly intended for system files
* Fix incorrect `final` placement
* Refactor how `DSi`'s NAND and SD card are set
- Provide them via a `DSiArgs` argument in the constructor
- Give `DSi_MMCStorage` ownership of the `NANDImage` or `FATStorage` as needed, and expose getters/setters
- Replace `DSi_SDHost::Ports` with a `array<unique_ptr, 2>` to reduce the risk of leaks
- Store `DSi_MMCStorage`'s disk images in a `std::variant`
- The SD card and NAND image are no longer reset in `Reset()`; the frontend will need to do that itself
* Add getters/setters on `DSi` itself for its storage media
* Remove newly-unused `Platform::ConfigEntry`s
* Use `DSi::SetNAND` in the frontend
* Add `EmuThread::NeedToRecreateConsole`
* Document `NDSArgs` and give its fields default values
* Refactor how system files are loaded upon construction
- Pass `NDSArgs&&` into `NDS`'s constructor
- Use `std::array` for the emulator's BIOS images and the built-in FreeBIOS, to simplify copying and comparison
- Initialize the BIOS, firmware, and SD cards from `NDSArgs` or `DSiArgs`
- Add a new default constructor for `NDS` (not `DSi`) that initializes the DS with default system files
- Embed `FirmwareMem::Firmware` directly instead of in a `unique_ptr`
- `SPIHost` now takes a `Firmware&&` that it forwards to `FirmwareMem`
- Add `Firmware` getters/setters plus `const` variants for `NDS`, `Firmware`, and `FirmwareMem`
- Simplify installation of firmware
* Initialize the DSi BIOS in the constructor
- Change `DSi::ARM9iBIOS` and `ARM7iBIOS` to `std::array`
* Update the frontend to reflect the core's changes
* Remove `DSi_SDHost::CloseHandles`
* Pass `nullopt` instead of the empty string when folder sync is off
* Deduplicate ROM extraction logic
- `LoadGBAROM` and `LoadROM` now delegate to `LoadROMData`
- Also use `unique_ptr` instead of `new[]`
* Oops, missed some `get()`'s
* Move `NDS::IsLoadedARM9BIOSBuiltIn` to the header
- So it's likelier to be inlined
- Same for the ARM7 version
* Remove `NDS::SetConsoleType`
* Add `NDS::SetFirmware`
* Move `GBACart::SetupSave` to be `protected`
- It was only ever used inside the class
* Rename `GBACart::LoadSave` to `SetSaveMemory`
- Same for the cart slot
* Declare `GBACartSlot` as a friend of `GBACart::CartCommon`
* Revise `GBACartSlot`'s getters and setters
- Rename `InsertROM` and `LoadROM` to `SetCart`
- Add a `GetCart` method
* Clean up getters and setters for NDS and GBA carts
* Clean up how carts are inserted into the slots
- Remove setters that operate directly on pointers, to simplify error-handling (use ParseROM instead)
- Add overloads for all carts that accept a `const u8*` (to copy the ROM data) and a `unique_ptr<u8[]>` (to move the ROM data)
- Store all ROM and RAM data in `unique_ptr`
- Default-initialize all fields
- Simplify constructors and destructors, inheriting where applicable
* Refactor GBA save data insertion
- Make `SetupSave` private and non-virtual and move its logic to be in `SetSaveMemory`
- Add overloads for setting save data in the constructor
- Update the SRAM completely in `SetSaveMemory`
* Clean up `NDSCart::CartCommon::SetSaveMemory`
- Move its declaration next to the other `SaveMemory` methods
- Move its (empty) implementation to the header
* Add some comments
* Add Utils.cpp and Utils.h
* Rename some functions in Utils for clarity
* Add `GBACart::ParseROM` and `NDSCart::ParseROM` overloads that accept `unique_ptr<u8[]>`
- The `u8*` overloads delegate to these new overloads
- Also move `SetupSave` for both kinds of carts to be private non-virtual methods
* Finalize the `NDSCart` refactor
- Add `NDSCartArgs` to pass to `ParseROM`
- Add SRAM arguments for all retail carts
- Initialize SRAM inside the constructor
- Delegate to other constructors where possible
* Replace `ROMManager::NDSSave` and `GBASave` with `unique_ptr`
* Make both cart slots return the previously-inserted cart in `EjectCart`
- Primarily intended for reusing carts when resetting the console
* Make `NDS::EjectCart` return the old cart
* Initialize both cart slots with the provided ROM (if any)
* Make `NDS::EjectGBACart` return the ejected cart
* Clean up some comments in Args.h
* Rename `ROMManager::LoadBIOS` to `BootToMenu`
- Clarifies the intent
* Add `ROMManager::LoadDLDISDCard`
* Add a doc comment
* Refactor how the `NDS` is created or updated
- Rewrite `CreateConsole` to read from `Config` and load system files, but accept carts as arguments
- Fail without creating an `NDS` if any required system file doesn't load
- Add `UpdateConsole`, which delegates to `CreateConsole` if switching modes or starting the app
- Use `std::variant` to indicate whether a cart should be removed, inserted, or reused
- Load all system files (plus SD cards) in `UpdateConsole`
- Eject the cart and reinsert it into the new console if applicable
* Respect some more `Config` settings in the `Load*` functions
* Remove `InstallNAND` in favor of `LoadNAND`
* Fix some potential bugs in `LoadROMData`
* Oops, forgot to delete the definition of `InstallNAND`
* Add functions to get `FATStorageArgs`
- Not the cards themselves, but to get the arguments you _would_ use to load the cards
* Refactor `ROMManager::LoadROM`
- Load the ROM and save data before trying to initialize the console
* Clean up `ROMManager::Reset` and `BootToMenu`
- Let `EmuThread::UpdateConsole` do the heavy lifting
* Clean up `LoadGBAROM`
* Remove some unused functions
* Set the default DSi BIOS to be broken in `DSiArgs`
* Respect `Config::DSiFullBIOSBoot` when loading DSi BIOS files
* Remove some more unused functions
* Remove redundant `virtual` specifiers
* Refactor `NDSCart::CartCommon::Type()` to return a member instead of a constant
- One less virtual dispatch
- The cart type is read in `NDSCartSlot::DoSavestate`, which is a path downstream (due to rewinding)
* Remove a hash that I computed for debugging purposes
* Make `ByteSwap` `constexpr`
* Remove an unused `#include`
* Remove unnecessary functions from the NDS carts
- Mostly overrides that added nothing
* Default-initialize all NDSCart fields
* Make `GBACart::Type()` not rely on virtual dispatch
- `GBACartSlot::DoSavestate` calls it, and savestates can be a hot path downstream
* Don't forget to reset the base class in `CartGameSolarSensor::Reset()`
* Remove redundant `virtual` specifiers
* Default-initialize some fields in `GBACart`
* Fix ROMs not loading from archives in the frontend
- Whoops
* Change how the `Firmware` member is declared
* Forgot an include in Utils.cpp
* Rename `FirmwareMem::Firmware` to `FirmwareData` to fix a build error on Linux
- One of these days I'll convince you people to let me use `camelCaseMemberNames`
* Add `override` to places in `DSi_MMCStorage` that warrant it
* Fix firmware saving on the frontend
- Remove `GetConfigString` and `ConfigEntry::WifiSettingsPath` while I'm at it
* Add a non-const `GetNAND()`
2023-12-04 16:57:22 +00:00
|
|
|
NDSCartSlot.SetSaveMemory(savedata, savelen);
|
2022-01-07 13:00:43 +00:00
|
|
|
}
|
|
|
|
|
Refactor how save data (including SD cards) is initialized (#1898)
* Remove `FATStorage::Open` and `FATStorage::Close`
- That's what the constructor and destructor are for, respectively
* Add `FATStorage::IsReadOnly`
* Slight cleanup of `FATStorage`
- Make it move-constructible and move-assignable
- Represent the absence of a sync directory with `std::optional`, not an empty string
- Add `FATStorageArgs` for later use
* Refactor `CartHomebrew` to accept an optional `FATStorageArgs`
- `CartHomebrew` uses it to load an SD card image
- Not passing a `FATStorage` directly because we won't know if we need to load the card until we parse the ROM
- Store the `FATStorage` inside a `std::optional` instead of a pointer
- `CartHomebrew::Reset` no longer reloads the SD card; the frontend needs to set it with the `SetSDCard` method
* Close `NANDImage::CurFile` when move-assigning
- Whoops
* Add `Args.h`
- To construct a `NDS` or `DSi` with arguments
- Mostly intended for system files
* Fix incorrect `final` placement
* Refactor how `DSi`'s NAND and SD card are set
- Provide them via a `DSiArgs` argument in the constructor
- Give `DSi_MMCStorage` ownership of the `NANDImage` or `FATStorage` as needed, and expose getters/setters
- Replace `DSi_SDHost::Ports` with a `array<unique_ptr, 2>` to reduce the risk of leaks
- Store `DSi_MMCStorage`'s disk images in a `std::variant`
- The SD card and NAND image are no longer reset in `Reset()`; the frontend will need to do that itself
* Add getters/setters on `DSi` itself for its storage media
* Remove newly-unused `Platform::ConfigEntry`s
* Use `DSi::SetNAND` in the frontend
* Add `EmuThread::NeedToRecreateConsole`
* Document `NDSArgs` and give its fields default values
* Refactor how system files are loaded upon construction
- Pass `NDSArgs&&` into `NDS`'s constructor
- Use `std::array` for the emulator's BIOS images and the built-in FreeBIOS, to simplify copying and comparison
- Initialize the BIOS, firmware, and SD cards from `NDSArgs` or `DSiArgs`
- Add a new default constructor for `NDS` (not `DSi`) that initializes the DS with default system files
- Embed `FirmwareMem::Firmware` directly instead of in a `unique_ptr`
- `SPIHost` now takes a `Firmware&&` that it forwards to `FirmwareMem`
- Add `Firmware` getters/setters plus `const` variants for `NDS`, `Firmware`, and `FirmwareMem`
- Simplify installation of firmware
* Initialize the DSi BIOS in the constructor
- Change `DSi::ARM9iBIOS` and `ARM7iBIOS` to `std::array`
* Update the frontend to reflect the core's changes
* Remove `DSi_SDHost::CloseHandles`
* Pass `nullopt` instead of the empty string when folder sync is off
* Deduplicate ROM extraction logic
- `LoadGBAROM` and `LoadROM` now delegate to `LoadROMData`
- Also use `unique_ptr` instead of `new[]`
* Oops, missed some `get()`'s
* Move `NDS::IsLoadedARM9BIOSBuiltIn` to the header
- So it's likelier to be inlined
- Same for the ARM7 version
* Remove `NDS::SetConsoleType`
* Add `NDS::SetFirmware`
* Move `GBACart::SetupSave` to be `protected`
- It was only ever used inside the class
* Rename `GBACart::LoadSave` to `SetSaveMemory`
- Same for the cart slot
* Declare `GBACartSlot` as a friend of `GBACart::CartCommon`
* Revise `GBACartSlot`'s getters and setters
- Rename `InsertROM` and `LoadROM` to `SetCart`
- Add a `GetCart` method
* Clean up getters and setters for NDS and GBA carts
* Clean up how carts are inserted into the slots
- Remove setters that operate directly on pointers, to simplify error-handling (use ParseROM instead)
- Add overloads for all carts that accept a `const u8*` (to copy the ROM data) and a `unique_ptr<u8[]>` (to move the ROM data)
- Store all ROM and RAM data in `unique_ptr`
- Default-initialize all fields
- Simplify constructors and destructors, inheriting where applicable
* Refactor GBA save data insertion
- Make `SetupSave` private and non-virtual and move its logic to be in `SetSaveMemory`
- Add overloads for setting save data in the constructor
- Update the SRAM completely in `SetSaveMemory`
* Clean up `NDSCart::CartCommon::SetSaveMemory`
- Move its declaration next to the other `SaveMemory` methods
- Move its (empty) implementation to the header
* Add some comments
* Add Utils.cpp and Utils.h
* Rename some functions in Utils for clarity
* Add `GBACart::ParseROM` and `NDSCart::ParseROM` overloads that accept `unique_ptr<u8[]>`
- The `u8*` overloads delegate to these new overloads
- Also move `SetupSave` for both kinds of carts to be private non-virtual methods
* Finalize the `NDSCart` refactor
- Add `NDSCartArgs` to pass to `ParseROM`
- Add SRAM arguments for all retail carts
- Initialize SRAM inside the constructor
- Delegate to other constructors where possible
* Replace `ROMManager::NDSSave` and `GBASave` with `unique_ptr`
* Make both cart slots return the previously-inserted cart in `EjectCart`
- Primarily intended for reusing carts when resetting the console
* Make `NDS::EjectCart` return the old cart
* Initialize both cart slots with the provided ROM (if any)
* Make `NDS::EjectGBACart` return the ejected cart
* Clean up some comments in Args.h
* Rename `ROMManager::LoadBIOS` to `BootToMenu`
- Clarifies the intent
* Add `ROMManager::LoadDLDISDCard`
* Add a doc comment
* Refactor how the `NDS` is created or updated
- Rewrite `CreateConsole` to read from `Config` and load system files, but accept carts as arguments
- Fail without creating an `NDS` if any required system file doesn't load
- Add `UpdateConsole`, which delegates to `CreateConsole` if switching modes or starting the app
- Use `std::variant` to indicate whether a cart should be removed, inserted, or reused
- Load all system files (plus SD cards) in `UpdateConsole`
- Eject the cart and reinsert it into the new console if applicable
* Respect some more `Config` settings in the `Load*` functions
* Remove `InstallNAND` in favor of `LoadNAND`
* Fix some potential bugs in `LoadROMData`
* Oops, forgot to delete the definition of `InstallNAND`
* Add functions to get `FATStorageArgs`
- Not the cards themselves, but to get the arguments you _would_ use to load the cards
* Refactor `ROMManager::LoadROM`
- Load the ROM and save data before trying to initialize the console
* Clean up `ROMManager::Reset` and `BootToMenu`
- Let `EmuThread::UpdateConsole` do the heavy lifting
* Clean up `LoadGBAROM`
* Remove some unused functions
* Set the default DSi BIOS to be broken in `DSiArgs`
* Respect `Config::DSiFullBIOSBoot` when loading DSi BIOS files
* Remove some more unused functions
* Remove redundant `virtual` specifiers
* Refactor `NDSCart::CartCommon::Type()` to return a member instead of a constant
- One less virtual dispatch
- The cart type is read in `NDSCartSlot::DoSavestate`, which is a path downstream (due to rewinding)
* Remove a hash that I computed for debugging purposes
* Make `ByteSwap` `constexpr`
* Remove an unused `#include`
* Remove unnecessary functions from the NDS carts
- Mostly overrides that added nothing
* Default-initialize all NDSCart fields
* Make `GBACart::Type()` not rely on virtual dispatch
- `GBACartSlot::DoSavestate` calls it, and savestates can be a hot path downstream
* Don't forget to reset the base class in `CartGameSolarSensor::Reset()`
* Remove redundant `virtual` specifiers
* Default-initialize some fields in `GBACart`
* Fix ROMs not loading from archives in the frontend
- Whoops
* Change how the `Firmware` member is declared
* Forgot an include in Utils.cpp
* Rename `FirmwareMem::Firmware` to `FirmwareData` to fix a build error on Linux
- One of these days I'll convince you people to let me use `camelCaseMemberNames`
* Add `override` to places in `DSi_MMCStorage` that warrant it
* Fix firmware saving on the frontend
- Remove `GetConfigString` and `ConfigEntry::WifiSettingsPath` while I'm at it
* Add a non-const `GetNAND()`
2023-12-04 16:57:22 +00:00
|
|
|
void NDS::SetGBASave(const u8* savedata, u32 savelen)
|
2022-01-07 13:00:43 +00:00
|
|
|
{
|
Refactor how save data (including SD cards) is initialized (#1898)
* Remove `FATStorage::Open` and `FATStorage::Close`
- That's what the constructor and destructor are for, respectively
* Add `FATStorage::IsReadOnly`
* Slight cleanup of `FATStorage`
- Make it move-constructible and move-assignable
- Represent the absence of a sync directory with `std::optional`, not an empty string
- Add `FATStorageArgs` for later use
* Refactor `CartHomebrew` to accept an optional `FATStorageArgs`
- `CartHomebrew` uses it to load an SD card image
- Not passing a `FATStorage` directly because we won't know if we need to load the card until we parse the ROM
- Store the `FATStorage` inside a `std::optional` instead of a pointer
- `CartHomebrew::Reset` no longer reloads the SD card; the frontend needs to set it with the `SetSDCard` method
* Close `NANDImage::CurFile` when move-assigning
- Whoops
* Add `Args.h`
- To construct a `NDS` or `DSi` with arguments
- Mostly intended for system files
* Fix incorrect `final` placement
* Refactor how `DSi`'s NAND and SD card are set
- Provide them via a `DSiArgs` argument in the constructor
- Give `DSi_MMCStorage` ownership of the `NANDImage` or `FATStorage` as needed, and expose getters/setters
- Replace `DSi_SDHost::Ports` with a `array<unique_ptr, 2>` to reduce the risk of leaks
- Store `DSi_MMCStorage`'s disk images in a `std::variant`
- The SD card and NAND image are no longer reset in `Reset()`; the frontend will need to do that itself
* Add getters/setters on `DSi` itself for its storage media
* Remove newly-unused `Platform::ConfigEntry`s
* Use `DSi::SetNAND` in the frontend
* Add `EmuThread::NeedToRecreateConsole`
* Document `NDSArgs` and give its fields default values
* Refactor how system files are loaded upon construction
- Pass `NDSArgs&&` into `NDS`'s constructor
- Use `std::array` for the emulator's BIOS images and the built-in FreeBIOS, to simplify copying and comparison
- Initialize the BIOS, firmware, and SD cards from `NDSArgs` or `DSiArgs`
- Add a new default constructor for `NDS` (not `DSi`) that initializes the DS with default system files
- Embed `FirmwareMem::Firmware` directly instead of in a `unique_ptr`
- `SPIHost` now takes a `Firmware&&` that it forwards to `FirmwareMem`
- Add `Firmware` getters/setters plus `const` variants for `NDS`, `Firmware`, and `FirmwareMem`
- Simplify installation of firmware
* Initialize the DSi BIOS in the constructor
- Change `DSi::ARM9iBIOS` and `ARM7iBIOS` to `std::array`
* Update the frontend to reflect the core's changes
* Remove `DSi_SDHost::CloseHandles`
* Pass `nullopt` instead of the empty string when folder sync is off
* Deduplicate ROM extraction logic
- `LoadGBAROM` and `LoadROM` now delegate to `LoadROMData`
- Also use `unique_ptr` instead of `new[]`
* Oops, missed some `get()`'s
* Move `NDS::IsLoadedARM9BIOSBuiltIn` to the header
- So it's likelier to be inlined
- Same for the ARM7 version
* Remove `NDS::SetConsoleType`
* Add `NDS::SetFirmware`
* Move `GBACart::SetupSave` to be `protected`
- It was only ever used inside the class
* Rename `GBACart::LoadSave` to `SetSaveMemory`
- Same for the cart slot
* Declare `GBACartSlot` as a friend of `GBACart::CartCommon`
* Revise `GBACartSlot`'s getters and setters
- Rename `InsertROM` and `LoadROM` to `SetCart`
- Add a `GetCart` method
* Clean up getters and setters for NDS and GBA carts
* Clean up how carts are inserted into the slots
- Remove setters that operate directly on pointers, to simplify error-handling (use ParseROM instead)
- Add overloads for all carts that accept a `const u8*` (to copy the ROM data) and a `unique_ptr<u8[]>` (to move the ROM data)
- Store all ROM and RAM data in `unique_ptr`
- Default-initialize all fields
- Simplify constructors and destructors, inheriting where applicable
* Refactor GBA save data insertion
- Make `SetupSave` private and non-virtual and move its logic to be in `SetSaveMemory`
- Add overloads for setting save data in the constructor
- Update the SRAM completely in `SetSaveMemory`
* Clean up `NDSCart::CartCommon::SetSaveMemory`
- Move its declaration next to the other `SaveMemory` methods
- Move its (empty) implementation to the header
* Add some comments
* Add Utils.cpp and Utils.h
* Rename some functions in Utils for clarity
* Add `GBACart::ParseROM` and `NDSCart::ParseROM` overloads that accept `unique_ptr<u8[]>`
- The `u8*` overloads delegate to these new overloads
- Also move `SetupSave` for both kinds of carts to be private non-virtual methods
* Finalize the `NDSCart` refactor
- Add `NDSCartArgs` to pass to `ParseROM`
- Add SRAM arguments for all retail carts
- Initialize SRAM inside the constructor
- Delegate to other constructors where possible
* Replace `ROMManager::NDSSave` and `GBASave` with `unique_ptr`
* Make both cart slots return the previously-inserted cart in `EjectCart`
- Primarily intended for reusing carts when resetting the console
* Make `NDS::EjectCart` return the old cart
* Initialize both cart slots with the provided ROM (if any)
* Make `NDS::EjectGBACart` return the ejected cart
* Clean up some comments in Args.h
* Rename `ROMManager::LoadBIOS` to `BootToMenu`
- Clarifies the intent
* Add `ROMManager::LoadDLDISDCard`
* Add a doc comment
* Refactor how the `NDS` is created or updated
- Rewrite `CreateConsole` to read from `Config` and load system files, but accept carts as arguments
- Fail without creating an `NDS` if any required system file doesn't load
- Add `UpdateConsole`, which delegates to `CreateConsole` if switching modes or starting the app
- Use `std::variant` to indicate whether a cart should be removed, inserted, or reused
- Load all system files (plus SD cards) in `UpdateConsole`
- Eject the cart and reinsert it into the new console if applicable
* Respect some more `Config` settings in the `Load*` functions
* Remove `InstallNAND` in favor of `LoadNAND`
* Fix some potential bugs in `LoadROMData`
* Oops, forgot to delete the definition of `InstallNAND`
* Add functions to get `FATStorageArgs`
- Not the cards themselves, but to get the arguments you _would_ use to load the cards
* Refactor `ROMManager::LoadROM`
- Load the ROM and save data before trying to initialize the console
* Clean up `ROMManager::Reset` and `BootToMenu`
- Let `EmuThread::UpdateConsole` do the heavy lifting
* Clean up `LoadGBAROM`
* Remove some unused functions
* Set the default DSi BIOS to be broken in `DSiArgs`
* Respect `Config::DSiFullBIOSBoot` when loading DSi BIOS files
* Remove some more unused functions
* Remove redundant `virtual` specifiers
* Refactor `NDSCart::CartCommon::Type()` to return a member instead of a constant
- One less virtual dispatch
- The cart type is read in `NDSCartSlot::DoSavestate`, which is a path downstream (due to rewinding)
* Remove a hash that I computed for debugging purposes
* Make `ByteSwap` `constexpr`
* Remove an unused `#include`
* Remove unnecessary functions from the NDS carts
- Mostly overrides that added nothing
* Default-initialize all NDSCart fields
* Make `GBACart::Type()` not rely on virtual dispatch
- `GBACartSlot::DoSavestate` calls it, and savestates can be a hot path downstream
* Don't forget to reset the base class in `CartGameSolarSensor::Reset()`
* Remove redundant `virtual` specifiers
* Default-initialize some fields in `GBACart`
* Fix ROMs not loading from archives in the frontend
- Whoops
* Change how the `Firmware` member is declared
* Forgot an include in Utils.cpp
* Rename `FirmwareMem::Firmware` to `FirmwareData` to fix a build error on Linux
- One of these days I'll convince you people to let me use `camelCaseMemberNames`
* Add `override` to places in `DSi_MMCStorage` that warrant it
* Fix firmware saving on the frontend
- Remove `GetConfigString` and `ConfigEntry::WifiSettingsPath` while I'm at it
* Add a non-const `GetNAND()`
2023-12-04 16:57:22 +00:00
|
|
|
if (ConsoleType == 0 && savedata && savelen)
|
|
|
|
{
|
|
|
|
GBACartSlot.SetSaveMemory(savedata, savelen);
|
|
|
|
}
|
2022-01-07 13:00:43 +00:00
|
|
|
|
2021-01-22 10:22:32 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::LoadGBAAddon(int type)
|
2017-03-29 16:59:20 +00:00
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
GBACartSlot.LoadAddon(type);
|
2016-11-24 17:31:49 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::LoadBIOS()
|
2022-01-07 13:00:43 +00:00
|
|
|
{
|
|
|
|
Reset();
|
|
|
|
}
|
2017-01-31 02:54:51 +00:00
|
|
|
|
2023-12-15 13:54:41 +00:00
|
|
|
void NDS::SetARM7BIOS(const std::array<u8, ARM7BIOSSize>& bios) noexcept
|
|
|
|
{
|
|
|
|
ARM7BIOS = bios;
|
|
|
|
ARM7BIOSNative = CRC32(ARM7BIOS.data(), ARM7BIOS.size()) == ARM7BIOSCRC32;
|
|
|
|
}
|
|
|
|
|
|
|
|
void NDS::SetARM9BIOS(const std::array<u8, ARM9BIOSSize>& bios) noexcept
|
|
|
|
{
|
|
|
|
ARM9BIOS = bios;
|
|
|
|
ARM9BIOSNative = CRC32(ARM9BIOS.data(), ARM9BIOS.size()) == ARM9BIOSCRC32;
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
u64 NDS::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
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::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
|
|
|
{
|
2023-11-02 20:04:09 +00:00
|
|
|
SchedEvent& evt = SchedList[i];
|
|
|
|
|
|
|
|
if (evt.Timestamp <= SysTimestamp)
|
2019-01-05 04:28:58 +00:00
|
|
|
{
|
|
|
|
SchedListMask &= ~(1<<i);
|
2023-11-02 20:04:09 +00:00
|
|
|
|
|
|
|
EventFunc func = evt.Funcs[evt.FuncID];
|
|
|
|
func(evt.Param);
|
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
|
|
|
}
|
|
|
|
}
|
2018-11-24 04:23:35 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
u64 NDS::NextTargetSleep()
|
2016-11-24 17:31:49 +00:00
|
|
|
{
|
2023-10-30 17:37:49 +00:00
|
|
|
u64 minEvent = UINT64_MAX;
|
2018-12-12 15:33:40 +00:00
|
|
|
|
2023-10-30 17:37:49 +00:00
|
|
|
u32 mask = SchedListMask;
|
|
|
|
for (int i = 0; i < Event_MAX; i++)
|
2017-01-31 02:54:51 +00:00
|
|
|
{
|
2023-10-30 17:37:49 +00:00
|
|
|
if (!mask) break;
|
|
|
|
if (i == Event_SPU || i == Event_RTC)
|
|
|
|
{
|
|
|
|
if (mask & 0x1)
|
|
|
|
{
|
|
|
|
if (SchedList[i].Timestamp < minEvent)
|
|
|
|
minEvent = SchedList[i].Timestamp;
|
|
|
|
}
|
|
|
|
}
|
2023-10-22 13:35:31 +00:00
|
|
|
|
2023-10-30 17:37:49 +00:00
|
|
|
mask >>= 1;
|
|
|
|
}
|
2018-11-23 21:21:41 +00:00
|
|
|
|
2023-10-30 17:37:49 +00:00
|
|
|
return minEvent;
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::RunSystemSleep(u64 timestamp)
|
2023-10-30 17:37:49 +00:00
|
|
|
{
|
|
|
|
u64 offset = timestamp - SysTimestamp;
|
|
|
|
SysTimestamp = timestamp;
|
2018-12-11 02:08:46 +00:00
|
|
|
|
2023-10-30 17:37:49 +00:00
|
|
|
u32 mask = SchedListMask;
|
|
|
|
for (int i = 0; i < Event_MAX; i++)
|
|
|
|
{
|
|
|
|
if (!mask) break;
|
|
|
|
if (i == Event_SPU || i == Event_RTC)
|
|
|
|
{
|
|
|
|
if (mask & 0x1)
|
2021-01-21 20:26:27 +00:00
|
|
|
{
|
2023-11-02 20:04:09 +00:00
|
|
|
SchedEvent& evt = SchedList[i];
|
|
|
|
|
|
|
|
if (evt.Timestamp <= SysTimestamp)
|
2023-10-30 17:37:49 +00:00
|
|
|
{
|
|
|
|
SchedListMask &= ~(1<<i);
|
2018-12-11 14:56:34 +00:00
|
|
|
|
2023-10-30 17:37:49 +00:00
|
|
|
u32 param;
|
|
|
|
if (i == Event_SPU)
|
|
|
|
param = 1;
|
|
|
|
else
|
2023-11-02 20:04:09 +00:00
|
|
|
param = evt.Param;
|
2023-10-30 17:37:49 +00:00
|
|
|
|
2023-11-02 20:04:09 +00:00
|
|
|
EventFunc func = evt.Funcs[evt.FuncID];
|
|
|
|
func(param);
|
2023-10-30 17:37:49 +00:00
|
|
|
}
|
2021-01-21 20:26:27 +00:00
|
|
|
}
|
2023-10-30 17:37:49 +00:00
|
|
|
}
|
|
|
|
else if (mask & 0x1)
|
|
|
|
{
|
|
|
|
if (SchedList[i].Timestamp <= SysTimestamp)
|
2019-01-05 04:28:58 +00:00
|
|
|
{
|
2023-10-30 17:37:49 +00:00
|
|
|
SchedList[i].Timestamp += offset;
|
2019-01-05 04:28:58 +00:00
|
|
|
}
|
2023-10-30 17:37:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mask >>= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
template <bool EnableJIT>
|
|
|
|
u32 NDS::RunFrame()
|
2023-10-30 17:37:49 +00:00
|
|
|
{
|
|
|
|
FrameStartTimestamp = SysTimestamp;
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
GPU.TotalScanlines = 0;
|
2023-10-30 17:37:49 +00:00
|
|
|
|
|
|
|
LagFrameFlag = true;
|
|
|
|
bool runFrame = Running && !(CPUStop & CPUStop_Sleep);
|
|
|
|
while (Running)
|
|
|
|
{
|
|
|
|
u64 frametarget = SysTimestamp + 560190;
|
|
|
|
|
|
|
|
if (CPUStop & CPUStop_Sleep)
|
|
|
|
{
|
|
|
|
// we are running in sleep mode
|
|
|
|
// we still need to run the RTC during this mode
|
|
|
|
// we also keep outputting audio, so that frontends using audio sync don't skyrocket to 1000+FPS
|
|
|
|
|
|
|
|
while (Running && (SysTimestamp < frametarget))
|
2019-01-05 04:28:58 +00:00
|
|
|
{
|
2023-10-30 17:37:49 +00:00
|
|
|
u64 target = NextTargetSleep();
|
|
|
|
if (target > frametarget)
|
|
|
|
target = frametarget;
|
|
|
|
|
|
|
|
ARM9Timestamp = target << ARM9ClockShift;
|
|
|
|
ARM7Timestamp = target;
|
|
|
|
TimerTimestamp[0] = target;
|
|
|
|
TimerTimestamp[1] = target;
|
2023-11-28 22:16:41 +00:00
|
|
|
GPU.GPU3D.Timestamp = target;
|
2023-10-30 17:37:49 +00:00
|
|
|
RunSystemSleep(target);
|
|
|
|
|
|
|
|
if (!(CPUStop & CPUStop_Sleep))
|
|
|
|
break;
|
2019-01-05 04:28:58 +00:00
|
|
|
}
|
2018-12-11 14:56:34 +00:00
|
|
|
|
2023-10-30 17:37:49 +00:00
|
|
|
if (SysTimestamp >= frametarget)
|
2023-11-28 22:16:41 +00:00
|
|
|
GPU.BlankFrame();
|
2023-10-30 17:37:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
ARM9.CheckGdbIncoming();
|
|
|
|
ARM7.CheckGdbIncoming();
|
2018-12-12 01:48:37 +00:00
|
|
|
|
2023-10-30 17:37:49 +00:00
|
|
|
if (!(CPUStop & CPUStop_Wakeup))
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
GPU.StartFrame();
|
2023-10-30 17:37:49 +00:00
|
|
|
}
|
|
|
|
CPUStop &= ~CPUStop_Wakeup;
|
2018-12-14 01:36:57 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
while (Running && GPU.TotalScanlines==0)
|
2021-01-21 20:26:27 +00:00
|
|
|
{
|
2023-10-30 17:37:49 +00:00
|
|
|
u64 target = NextTarget();
|
|
|
|
ARM9Target = target << ARM9ClockShift;
|
|
|
|
CurCPU = 0;
|
2021-01-21 20:26:27 +00:00
|
|
|
|
2023-10-30 17:37:49 +00:00
|
|
|
if (CPUStop & CPUStop_GXStall)
|
2021-01-21 20:26:27 +00:00
|
|
|
{
|
2023-10-30 17:37:49 +00:00
|
|
|
// GXFIFO stall
|
2023-11-28 22:16:41 +00:00
|
|
|
s32 cycles = GPU.GPU3D.CyclesToRunFor();
|
2023-10-30 17:37:49 +00:00
|
|
|
|
|
|
|
ARM9Timestamp = std::min(ARM9Target, ARM9Timestamp+(cycles<<ARM9ClockShift));
|
|
|
|
}
|
|
|
|
else if (CPUStop & CPUStop_DMA9)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
DMAs[0].Run();
|
|
|
|
if (!(CPUStop & CPUStop_GXStall)) DMAs[1].Run();
|
|
|
|
if (!(CPUStop & CPUStop_GXStall)) DMAs[2].Run();
|
|
|
|
if (!(CPUStop & CPUStop_GXStall)) DMAs[3].Run();
|
|
|
|
if (ConsoleType == 1)
|
|
|
|
{
|
|
|
|
auto& dsi = dynamic_cast<melonDS::DSi&>(*this);
|
|
|
|
dsi.RunNDMAs(0);
|
|
|
|
}
|
2021-01-21 20:26:27 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef JIT_ENABLED
|
|
|
|
if (EnableJIT)
|
2023-11-28 22:16:41 +00:00
|
|
|
ARM9.ExecuteJIT();
|
2021-01-21 20:26:27 +00:00
|
|
|
else
|
|
|
|
#endif
|
2023-11-28 22:16:41 +00:00
|
|
|
ARM9.Execute();
|
2021-01-21 20:26:27 +00:00
|
|
|
}
|
|
|
|
|
2023-10-30 17:37:49 +00:00
|
|
|
RunTimers(0);
|
2023-11-28 22:16:41 +00:00
|
|
|
GPU.GPU3D.Run();
|
2021-01-21 20:26:27 +00:00
|
|
|
|
2023-10-30 17:37:49 +00:00
|
|
|
target = ARM9Timestamp >> ARM9ClockShift;
|
|
|
|
CurCPU = 1;
|
2021-01-21 20:26:27 +00:00
|
|
|
|
2023-10-30 17:37:49 +00:00
|
|
|
while (ARM7Timestamp < target)
|
|
|
|
{
|
|
|
|
ARM7Target = target; // might be changed by a reschedule
|
|
|
|
|
|
|
|
if (CPUStop & CPUStop_DMA7)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
DMAs[4].Run();
|
|
|
|
DMAs[5].Run();
|
|
|
|
DMAs[6].Run();
|
|
|
|
DMAs[7].Run();
|
|
|
|
if (ConsoleType == 1)
|
|
|
|
{
|
|
|
|
auto& dsi = dynamic_cast<melonDS::DSi&>(*this);
|
|
|
|
dsi.RunNDMAs(1);
|
|
|
|
}
|
2023-10-30 17:37:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef JIT_ENABLED
|
|
|
|
if (EnableJIT)
|
2023-11-28 22:16:41 +00:00
|
|
|
ARM7.ExecuteJIT();
|
2023-10-30 17:37:49 +00:00
|
|
|
else
|
|
|
|
#endif
|
2023-11-28 22:16:41 +00:00
|
|
|
ARM7.Execute();
|
2023-10-30 17:37:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
RunTimers(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
RunSystem(target);
|
|
|
|
|
|
|
|
if (CPUStop & CPUStop_Sleep)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2021-01-21 20:26:27 +00:00
|
|
|
}
|
2018-12-14 01:36:57 +00:00
|
|
|
}
|
2018-11-24 04:23:35 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
if (GPU.TotalScanlines == 0)
|
2023-10-30 17:37:49 +00:00
|
|
|
continue;
|
|
|
|
|
2018-12-11 14:56:34 +00:00
|
|
|
#ifdef DEBUG_CHECK_DESYNC
|
2023-03-23 17:04:38 +00:00
|
|
|
Log(LogLevel::Debug, "[%08X%08X] ARM9=%ld, ARM7=%ld, GPU=%ld\n",
|
2021-01-21 20:26:27 +00:00
|
|
|
(u32)(SysTimestamp>>32), (u32)SysTimestamp,
|
|
|
|
(ARM9Timestamp>>1)-SysTimestamp,
|
|
|
|
ARM7Timestamp-SysTimestamp,
|
2023-11-28 22:16:41 +00:00
|
|
|
GPU.GPU3D.Timestamp-SysTimestamp);
|
2018-12-11 14:56:34 +00:00
|
|
|
#endif
|
2023-11-28 22:16:41 +00:00
|
|
|
SPU.TransferOutput();
|
2023-10-30 17:37:49 +00:00
|
|
|
break;
|
2021-01-21 20:26:27 +00:00
|
|
|
}
|
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
|
|
|
|
2023-10-30 17:37:49 +00:00
|
|
|
if (Running)
|
2023-11-28 22:16:41 +00:00
|
|
|
return GPU.TotalScanlines;
|
2021-01-21 20:26:27 +00:00
|
|
|
else
|
|
|
|
return 263;
|
2016-12-05 16:08:24 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
u32 NDS::RunFrame()
|
2019-07-14 02:33:36 +00:00
|
|
|
{
|
2019-07-14 17:24:00 +00:00
|
|
|
#ifdef JIT_ENABLED
|
2021-11-17 17:15:50 +00:00
|
|
|
if (EnableJIT)
|
2023-11-28 22:16:41 +00:00
|
|
|
return RunFrame<true>();
|
2019-07-14 02:33:36 +00:00
|
|
|
else
|
2019-07-14 17:24:00 +00:00
|
|
|
#endif
|
2023-11-28 22:16:41 +00:00
|
|
|
return RunFrame<false>();
|
2019-07-14 02:33:36 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::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
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::RegisterEventFunc(u32 id, u32 funcid, EventFunc func)
|
2023-11-02 20:04:09 +00:00
|
|
|
{
|
|
|
|
SchedEvent& evt = SchedList[id];
|
|
|
|
|
|
|
|
evt.Funcs[funcid] = func;
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::UnregisterEventFunc(u32 id, u32 funcid)
|
2023-11-02 20:04:09 +00:00
|
|
|
{
|
|
|
|
SchedEvent& evt = SchedList[id];
|
|
|
|
|
|
|
|
evt.Funcs.erase(funcid);
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::ScheduleEvent(u32 id, bool periodic, s32 delay, u32 funcid, u32 param)
|
2017-01-31 02:54:51 +00:00
|
|
|
{
|
|
|
|
if (SchedListMask & (1<<id))
|
|
|
|
{
|
2023-03-23 17:04:38 +00:00
|
|
|
Log(LogLevel::Debug, "!! EVENT %d ALREADY SCHEDULED\n", id);
|
2017-01-31 02:54:51 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-11-02 20:04:09 +00:00
|
|
|
SchedEvent& evt = SchedList[id];
|
2017-01-31 02:54:51 +00:00
|
|
|
|
2018-12-11 02:08:46 +00:00
|
|
|
if (periodic)
|
2023-11-02 20:04:09 +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)
|
2023-11-02 20:04:09 +00:00
|
|
|
evt.Timestamp = (ARM9Timestamp >> ARM9ClockShift) + delay;
|
2019-01-05 04:28:58 +00:00
|
|
|
else
|
2023-11-02 20:04:09 +00:00
|
|
|
evt.Timestamp = ARM7Timestamp + delay;
|
2018-12-11 02:08:46 +00:00
|
|
|
}
|
2017-01-31 02:54:51 +00:00
|
|
|
|
2023-11-02 20:04:09 +00:00
|
|
|
evt.FuncID = funcid;
|
|
|
|
evt.Param = param;
|
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
|
|
|
|
|
|
|
SchedListMask |= (1<<id);
|
|
|
|
|
2023-11-02 20:04:09 +00:00
|
|
|
Reschedule(evt.Timestamp);
|
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
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::CancelEvent(u32 id)
|
2017-01-31 02:54:51 +00:00
|
|
|
{
|
|
|
|
SchedListMask &= ~(1<<id);
|
|
|
|
}
|
|
|
|
|
2016-11-24 17:31:49 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::TouchScreen(u16 x, u16 y)
|
2017-01-31 23:24:36 +00:00
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
SPI.GetTSC()->SetTouchCoords(x, y);
|
2017-01-31 23:24:36 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::ReleaseScreen()
|
2017-01-31 23:24:36 +00:00
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
SPI.GetTSC()->SetTouchCoords(0x000, 0xFFF);
|
2017-01-31 23:24:36 +00:00
|
|
|
}
|
|
|
|
|
2016-12-23 20:22:22 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::CheckKeyIRQ(u32 cpu, u32 oldkey, u32 newkey)
|
2023-10-30 17:37:49 +00:00
|
|
|
{
|
|
|
|
u16 cnt = KeyCnt[cpu];
|
|
|
|
if (!(cnt & (1<<14))) // IRQ disabled
|
|
|
|
return;
|
|
|
|
|
|
|
|
u32 mask = (cnt & 0x03FF);
|
|
|
|
oldkey &= mask;
|
|
|
|
newkey &= mask;
|
|
|
|
|
|
|
|
bool oldmatch, newmatch;
|
|
|
|
if (cnt & (1<<15))
|
|
|
|
{
|
|
|
|
// logical AND
|
|
|
|
|
|
|
|
oldmatch = (oldkey == 0);
|
|
|
|
newmatch = (newkey == 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// logical OR
|
|
|
|
|
|
|
|
oldmatch = (oldkey != mask);
|
|
|
|
newmatch = (newkey != mask);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((!oldmatch) && newmatch)
|
|
|
|
SetIRQ(cpu, IRQ_Keypad);
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::SetKeyMask(u32 mask)
|
2017-09-30 18:05:56 +00:00
|
|
|
{
|
|
|
|
u32 key_lo = mask & 0x3FF;
|
|
|
|
u32 key_hi = (mask >> 10) & 0x3;
|
|
|
|
|
2023-10-30 17:37:49 +00:00
|
|
|
u32 oldkey = KeyInput;
|
2017-09-30 18:05:56 +00:00
|
|
|
KeyInput &= 0xFFFCFC00;
|
|
|
|
KeyInput |= key_lo | (key_hi << 16);
|
2023-10-30 17:37:49 +00:00
|
|
|
|
|
|
|
CheckKeyIRQ(0, oldkey, KeyInput);
|
|
|
|
CheckKeyIRQ(1, oldkey, KeyInput);
|
2017-09-30 18:05:56 +00:00
|
|
|
}
|
|
|
|
|
2023-12-12 10:07:22 +00:00
|
|
|
bool NDS::IsLidClosed() const
|
2020-05-19 20:37:48 +00:00
|
|
|
{
|
|
|
|
if (KeyInput & (1<<23)) return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::SetLidClosed(bool closed)
|
2018-12-14 01:36:57 +00:00
|
|
|
{
|
|
|
|
if (closed)
|
|
|
|
{
|
|
|
|
KeyInput |= (1<<23);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
KeyInput &= ~(1<<23);
|
|
|
|
SetIRQ(1, IRQ_LidOpen);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::MicInputFrame(s16* data, int samples)
|
2018-12-12 15:33:40 +00:00
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
return SPI.GetTSC()->MicInputFrame(data, samples);
|
2018-12-12 15:33:40 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::Halt()
|
2016-11-24 17:31:49 +00:00
|
|
|
{
|
2023-03-23 17:04:38 +00:00
|
|
|
Log(LogLevel::Info, "Halt()\n");
|
2016-11-24 17:31:49 +00:00
|
|
|
Running = false;
|
2016-11-03 00:38:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::MapSharedWRAM(u8 val)
|
2016-12-03 17:29:19 +00:00
|
|
|
{
|
2020-05-08 22:45:05 +00:00
|
|
|
if (val == WRAMCnt)
|
|
|
|
return;
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.Memory.RemapSWRAM();
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::UpdateWifiTimings()
|
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 & 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::SetWifiWaitCnt(u16 val)
|
2018-12-08 21:33:41 +00:00
|
|
|
{
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::SetGBASlotTimings()
|
2018-12-08 21:33:41 +00:00
|
|
|
{
|
|
|
|
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
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
GBACartSlot.SetOpenBusDecay(openbus[(curcnt>>2) & 0x3]);
|
2018-12-08 21:33:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::UpdateIRQ(u32 cpu)
|
2019-06-08 20:16:51 +00:00
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
ARM& arm = cpu ? (ARM&)ARM7 : (ARM&)ARM9;
|
2019-06-08 20:16:51 +00:00
|
|
|
|
|
|
|
if (IME[cpu] & 0x1)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
arm.IRQ = !!(IE[cpu] & IF[cpu]);
|
2020-06-01 18:36:30 +00:00
|
|
|
if ((ConsoleType == 1) && cpu)
|
2023-11-28 22:16:41 +00:00
|
|
|
arm.IRQ |= !!(IE2 & IF2);
|
2019-06-08 20:16:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
arm.IRQ = 0;
|
2019-06-08 20:16:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::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);
|
2023-10-30 17:37:49 +00:00
|
|
|
|
|
|
|
if ((cpu == 1) && (CPUStop & CPUStop_Sleep))
|
|
|
|
{
|
|
|
|
if (IE[1] & (1 << irq))
|
|
|
|
{
|
|
|
|
CPUStop &= ~CPUStop_Sleep;
|
|
|
|
CPUStop |= CPUStop_Wakeup;
|
2023-12-15 13:53:31 +00:00
|
|
|
GPU.GPU3D.RestartFrame(GPU);
|
2023-10-30 17:37:49 +00:00
|
|
|
}
|
|
|
|
}
|
2017-03-02 23:48:26 +00:00
|
|
|
}
|
2016-12-06 16:32:51 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::ClearIRQ(u32 cpu, u32 irq)
|
2017-03-02 23:48:26 +00:00
|
|
|
{
|
|
|
|
IF[cpu] &= ~(1 << irq);
|
2019-06-08 20:16:51 +00:00
|
|
|
UpdateIRQ(cpu);
|
2016-12-04 02:20:50 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::SetIRQ2(u32 irq)
|
2019-06-16 13:05:18 +00:00
|
|
|
{
|
|
|
|
IF2 |= (1 << irq);
|
|
|
|
UpdateIRQ(1);
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::ClearIRQ2(u32 irq)
|
2019-06-16 13:05:18 +00:00
|
|
|
{
|
|
|
|
IF2 &= ~(1 << irq);
|
|
|
|
UpdateIRQ(1);
|
|
|
|
}
|
|
|
|
|
2023-12-12 10:07:22 +00:00
|
|
|
bool NDS::HaltInterrupted(u32 cpu) const
|
2016-12-06 16:32:51 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::StopCPU(u32 cpu, u32 mask)
|
2017-03-02 23:48:26 +00:00
|
|
|
{
|
2017-04-12 15:53:15 +00:00
|
|
|
if (cpu)
|
|
|
|
{
|
|
|
|
CPUStop |= (mask << 16);
|
2023-11-28 22:16:41 +00:00
|
|
|
ARM7.Halt(2);
|
2017-04-12 15:53:15 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CPUStop |= mask;
|
2023-11-28 22:16:41 +00:00
|
|
|
ARM9.Halt(2);
|
2017-04-12 15:53:15 +00:00
|
|
|
}
|
2017-03-02 23:48:26 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::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
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::GXFIFOStall()
|
2018-11-23 21:21:41 +00:00
|
|
|
{
|
2023-10-30 17:37:49 +00:00
|
|
|
if (CPUStop & CPUStop_GXStall) return;
|
2018-12-11 14:56:34 +00:00
|
|
|
|
2023-10-30 17:37:49 +00:00
|
|
|
CPUStop |= CPUStop_GXStall;
|
2018-11-23 21:21:41 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
if (CurCPU == 1) ARM9.Halt(2);
|
2018-11-23 21:21:41 +00:00
|
|
|
else
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
DMAs[0].StallIfRunning();
|
|
|
|
DMAs[1].StallIfRunning();
|
|
|
|
DMAs[2].StallIfRunning();
|
|
|
|
DMAs[3].StallIfRunning();
|
|
|
|
if (ConsoleType == 1)
|
|
|
|
{
|
|
|
|
auto& dsi = dynamic_cast<melonDS::DSi&>(*this);
|
|
|
|
dsi.StallNDMAs();
|
|
|
|
}
|
2018-11-23 21:21:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::GXFIFOUnstall()
|
2018-11-23 21:21:41 +00:00
|
|
|
{
|
2023-10-30 17:37:49 +00:00
|
|
|
CPUStop &= ~CPUStop_GXStall;
|
2018-11-23 21:21:41 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::EnterSleepMode()
|
2018-12-14 01:36:57 +00:00
|
|
|
{
|
2023-10-30 17:37:49 +00:00
|
|
|
if (CPUStop & CPUStop_Sleep) return;
|
2018-12-14 01:36:57 +00:00
|
|
|
|
2023-10-30 17:37:49 +00:00
|
|
|
CPUStop |= CPUStop_Sleep;
|
2023-11-28 22:16:41 +00:00
|
|
|
ARM7.Halt(2);
|
2018-12-14 01:36:57 +00:00
|
|
|
}
|
|
|
|
|
2023-12-12 10:07:22 +00:00
|
|
|
u32 NDS::GetPC(u32 cpu) const
|
2017-06-25 15:35:45 +00:00
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
return cpu ? ARM7.R[15] : ARM9.R[15];
|
2017-06-25 15:35:45 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
u64 NDS::GetSysClockCycles(int num)
|
2018-12-12 01:48:37 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::NocashPrint(u32 ncpu, u32 addr)
|
2018-12-12 01:48:37 +00:00
|
|
|
{
|
2021-05-27 10:15:16 +00:00
|
|
|
// addr: debug string
|
2018-12-12 01:48:37 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
ARM* cpu = ncpu ? (ARM*)&ARM7 : (ARM*)&ARM9;
|
|
|
|
u8 (NDS::*readfn)(u32) = ncpu ? &NDS::ARM7Read8 : &NDS::ARM9Read8;
|
2018-12-12 01:48:37 +00:00
|
|
|
|
|
|
|
char output[1024];
|
|
|
|
int ptr = 0;
|
|
|
|
|
|
|
|
for (int i = 0; i < 120 && ptr < 1023; )
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
char ch = (this->*readfn)(addr++);
|
2018-12-12 01:48:37 +00:00
|
|
|
i++;
|
|
|
|
|
|
|
|
if (ch == '%')
|
|
|
|
{
|
|
|
|
char cmd[16]; int j;
|
|
|
|
for (j = 0; j < 15; )
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
char ch2 = (this->*readfn)(addr++);
|
2018-12-12 01:48:37 +00:00
|
|
|
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);
|
2023-11-28 22:16:41 +00:00
|
|
|
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';
|
2023-03-23 17:04:38 +00:00
|
|
|
Log(LogLevel::Debug, "%s", output);
|
2018-12-12 01:48:37 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::MonitorARM9Jump(u32 addr)
|
2020-02-24 17:31:44 +00:00
|
|
|
{
|
|
|
|
// 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
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
if ((!RunningGame) && NDSCartSlot.GetCart())
|
2020-02-24 17:31:44 +00:00
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
const NDSHeader& header = NDSCartSlot.GetCart()->GetHeader();
|
2023-06-30 11:28:52 +00:00
|
|
|
if (addr == header.ARM9EntryAddress)
|
2021-08-30 18:28:51 +00:00
|
|
|
{
|
2023-03-23 17:04:38 +00:00
|
|
|
Log(LogLevel::Info, "Game is now booting\n");
|
2020-02-24 17:31:44 +00:00
|
|
|
RunningGame = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::HandleTimerOverflow(u32 tid)
|
2017-03-20 16:39:42 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::RunTimer(u32 tid, s32 cycles)
|
2017-03-20 16:39:42 +00:00
|
|
|
{
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::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};
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
u16 NDS::TimerGetCounter(u32 timer)
|
2021-08-31 00:28:34 +00:00
|
|
|
{
|
|
|
|
RunTimers(timer>>2);
|
|
|
|
u32 ret = Timers[timer].Counter;
|
|
|
|
|
|
|
|
return ret >> 10;
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::TimerStart(u32 id, u16 cnt)
|
2021-08-31 00:28:34 +00:00
|
|
|
{
|
|
|
|
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
|
|
|
|
|
|
|
|
2023-12-12 10:07:22 +00:00
|
|
|
bool NDS::DMAsInMode(u32 cpu, u32 mode) const
|
2017-06-26 09:02:10 +00:00
|
|
|
{
|
|
|
|
cpu <<= 2;
|
2023-11-28 22:16:41 +00:00
|
|
|
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
|
|
|
|
2017-06-26 09:02:10 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2023-12-12 10:07:22 +00:00
|
|
|
bool NDS::DMAsRunning(u32 cpu) const
|
2018-12-11 02:08:46 +00:00
|
|
|
{
|
|
|
|
cpu <<= 2;
|
2023-11-28 22:16:41 +00:00
|
|
|
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;
|
|
|
|
|
2018-12-11 02:08:46 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::CheckDMAs(u32 cpu, u32 mode)
|
2017-01-22 19:34:59 +00:00
|
|
|
{
|
|
|
|
cpu <<= 2;
|
2023-11-28 22:16:41 +00:00
|
|
|
DMAs[cpu+0].StartIfNeeded(mode);
|
|
|
|
DMAs[cpu+1].StartIfNeeded(mode);
|
|
|
|
DMAs[cpu+2].StartIfNeeded(mode);
|
|
|
|
DMAs[cpu+3].StartIfNeeded(mode);
|
2017-01-22 19:34:59 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::StopDMAs(u32 cpu, u32 mode)
|
2017-03-20 21:18:35 +00:00
|
|
|
{
|
|
|
|
cpu <<= 2;
|
2023-11-28 22:16:41 +00:00
|
|
|
DMAs[cpu+0].StopIfNeeded(mode);
|
|
|
|
DMAs[cpu+1].StopIfNeeded(mode);
|
|
|
|
DMAs[cpu+2].StopIfNeeded(mode);
|
|
|
|
DMAs[cpu+3].StopIfNeeded(mode);
|
2017-03-20 21:18:35 +00:00
|
|
|
}
|
|
|
|
|
2017-01-22 19:34:59 +00:00
|
|
|
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::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
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::StartDiv()
|
2017-01-31 20:53:45 +00:00
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
CancelEvent(Event_Div);
|
2017-07-15 17:46:27 +00:00
|
|
|
DivCnt |= 0x8000;
|
2023-11-28 22:16:41 +00:00
|
|
|
ScheduleEvent(Event_Div, false, ((DivCnt&0x3)==0) ? 18:34, 0, 0);
|
2017-07-15 17:46:27 +00:00
|
|
|
}
|
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
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::SqrtDone(u32 param)
|
2017-07-15 17:46:27 +00:00
|
|
|
{
|
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;
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::StartSqrt()
|
2017-07-15 17:46:27 +00:00
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
CancelEvent(Event_Sqrt);
|
2017-07-15 17:46:27 +00:00
|
|
|
SqrtCnt |= 0x8000;
|
2023-11-28 22:16:41 +00:00
|
|
|
ScheduleEvent(Event_Sqrt, false, 13, 0, 0);
|
2017-07-15 17:46:27 +00:00
|
|
|
}
|
|
|
|
|
2017-01-18 01:20:45 +00:00
|
|
|
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::debug(u32 param)
|
2016-12-06 16:32:51 +00:00
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
Log(LogLevel::Debug, "ARM9 PC=%08X LR=%08X %08X\n", ARM9.R[15], ARM9.R[14], ARM9.R_IRQ[1]);
|
|
|
|
Log(LogLevel::Debug, "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
|
|
|
|
2023-03-23 17:04:38 +00:00
|
|
|
Log(LogLevel::Debug, "ARM9 IME=%08X IE=%08X IF=%08X\n", IME[0], IE[0], IF[0]);
|
|
|
|
Log(LogLevel::Debug, "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++)
|
2023-11-09 20:54:51 +00:00
|
|
|
// printf("VRAM %c: %02X\n", 'A'+i, GPU->VRAMCNT[i]);
|
2017-04-26 14:17:03 +00:00
|
|
|
|
2023-11-24 18:17:22 +00:00
|
|
|
Platform::FileHandle* shit = Platform::OpenFile("debug/DSfirmware.bin", FileMode::Write);
|
2023-11-28 22:16:41 +00:00
|
|
|
Platform::FileWrite(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
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
u32 val = NDS::ARM7Read32(i);
|
2023-11-24 18:17:22 +00:00
|
|
|
Platform::FileWrite(&val, 4, 1, shit);
|
2017-04-26 14:17:03 +00:00
|
|
|
}
|
2017-05-09 01:54:37 +00:00
|
|
|
for (u32 i = 0x037F0000; i < 0x03810000; i+=4)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
u32 val = NDS::ARM7Read32(i);
|
2023-11-24 18:17:22 +00:00
|
|
|
Platform::FileWrite(&val, 4, 1, shit);
|
2017-05-09 01:54:37 +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
|
|
|
for (u32 i = 0x06000000; i < 0x06040000; i+=4)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
u32 val = NDS::ARM7Read32(i);
|
2023-11-24 18:17:22 +00:00
|
|
|
Platform::FileWrite(&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
|
|
|
}
|
2023-11-24 18:17:22 +00:00
|
|
|
Platform::CloseFile(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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
u8 NDS::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:
|
2023-11-28 22:16:41 +00:00
|
|
|
// Specifically want to call the NDS version, not a subclass
|
|
|
|
return NDS::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;
|
2023-11-28 22:16:41 +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
|
|
|
{
|
2023-11-28 22:16: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;
|
2023-11-28 22:16:41 +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
|
2023-11-28 22:16:41 +00:00
|
|
|
if (addr & 0x1) return GBACartSlot.ROMRead(addr-1) >> 8;
|
|
|
|
return GBACartSlot.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
|
2023-11-28 22:16:41 +00:00
|
|
|
return GBACartSlot.SRAMRead(addr);
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
2023-08-18 20:50:57 +00:00
|
|
|
Log(LogLevel::Debug, "unknown arm9 read8 %08X\n", addr);
|
2018-12-08 21:33:41 +00:00
|
|
|
return 0;
|
2016-12-03 00:31:33 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
u16 NDS::ARM9Read16(u32 addr)
|
2016-11-03 00:38:58 +00:00
|
|
|
{
|
2022-10-22 11:11:57 +00:00
|
|
|
addr &= ~0x1;
|
|
|
|
|
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:
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDS::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;
|
2023-11-28 22:16:41 +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
|
|
|
{
|
2023-11-28 22:16: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;
|
2023-11-28 22:16:41 +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
|
2023-11-28 22:16:41 +00:00
|
|
|
return GBACartSlot.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
|
2023-11-28 22:16:41 +00:00
|
|
|
return GBACartSlot.SRAMRead(addr) |
|
|
|
|
(GBACartSlot.SRAMRead(addr+1) << 8);
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
//if (addr) Log(LogLevel::Warn, "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
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
u32 NDS::ARM9Read32(u32 addr)
|
2016-12-03 00:31:33 +00:00
|
|
|
{
|
2022-10-22 11:11:57 +00:00
|
|
|
addr &= ~0x3;
|
|
|
|
|
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:
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDS::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;
|
2023-11-28 22:16:41 +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
|
|
|
{
|
2023-11-28 22:16: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;
|
2023-11-28 22:16:41 +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
|
2023-11-28 22:16:41 +00:00
|
|
|
return GBACartSlot.ROMRead(addr) |
|
|
|
|
(GBACartSlot.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
|
2023-11-28 22:16:41 +00:00
|
|
|
return GBACartSlot.SRAMRead(addr) |
|
|
|
|
(GBACartSlot.SRAMRead(addr+1) << 8) |
|
|
|
|
(GBACartSlot.SRAMRead(addr+2) << 16) |
|
|
|
|
(GBACartSlot.SRAMRead(addr+3) << 24);
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
//Log(LogLevel::Warn, "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
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::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:
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_MainRAM>(addr);
|
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
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_SharedWRAM>(addr);
|
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:
|
2023-11-28 22:16:41 +00:00
|
|
|
NDS::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
|
2023-11-28 22:16:41 +00:00
|
|
|
GBACartSlot.SRAMWrite(addr, val);
|
2019-12-08 22:56:22 +00:00
|
|
|
return;
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
2023-08-18 20:50:57 +00:00
|
|
|
Log(LogLevel::Debug, "unknown arm9 write8 %08X %02X\n", addr, val);
|
2016-12-03 00:31:33 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::ARM9Write16(u32 addr, u16 val)
|
2016-12-03 00:31:33 +00:00
|
|
|
{
|
2022-10-22 11:11:57 +00:00
|
|
|
addr &= ~0x1;
|
|
|
|
|
2016-12-03 12:42:27 +00:00
|
|
|
switch (addr & 0xFF000000)
|
|
|
|
{
|
|
|
|
case 0x02000000:
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_MainRAM>(addr);
|
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
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_SharedWRAM>(addr);
|
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:
|
2023-11-28 22:16:41 +00:00
|
|
|
NDS::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;
|
2023-11-28 22:16:41 +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:
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_VRAM>(addr);
|
2017-02-27 20:26:11 +00:00
|
|
|
switch (addr & 0x00E00000)
|
2016-12-05 22:17:03 +00:00
|
|
|
{
|
2023-11-28 22:16: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;
|
|
|
|
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;
|
2023-11-28 22:16:41 +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
|
2023-11-28 22:16:41 +00:00
|
|
|
GBACartSlot.ROMWrite(addr, val);
|
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
|
2023-11-28 22:16:41 +00:00
|
|
|
GBACartSlot.SRAMWrite(addr, val & 0xFF);
|
|
|
|
GBACartSlot.SRAMWrite(addr+1, val >> 8);
|
2019-12-08 22:56:22 +00:00
|
|
|
return;
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
2023-03-23 17:04:38 +00:00
|
|
|
//if (addr) Log(LogLevel::Warn, "unknown arm9 write16 %08X %04X\n", addr, val);
|
2016-12-03 00:31:33 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::ARM9Write32(u32 addr, u32 val)
|
2018-12-18 01:00:50 +00:00
|
|
|
{
|
2022-10-22 11:11:57 +00:00
|
|
|
addr &= ~0x3;
|
|
|
|
|
2016-12-03 12:42:27 +00:00
|
|
|
switch (addr & 0xFF000000)
|
|
|
|
{
|
|
|
|
case 0x02000000:
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_MainRAM>(addr);
|
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
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_SharedWRAM>(addr);
|
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:
|
2023-11-28 22:16:41 +00:00
|
|
|
NDS::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;
|
2023-11-28 22:16:41 +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:
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_VRAM>(addr);
|
2017-02-27 20:26:11 +00:00
|
|
|
switch (addr & 0x00E00000)
|
2016-12-05 22:17:03 +00:00
|
|
|
{
|
2023-11-28 22:16: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;
|
|
|
|
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;
|
2023-11-28 22:16:41 +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
|
2023-11-28 22:16:41 +00:00
|
|
|
GBACartSlot.ROMWrite(addr, val & 0xFFFF);
|
|
|
|
GBACartSlot.ROMWrite(addr+2, val >> 16);
|
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
|
2023-11-28 22:16:41 +00:00
|
|
|
GBACartSlot.SRAMWrite(addr, val & 0xFF);
|
|
|
|
GBACartSlot.SRAMWrite(addr+1, (val >> 8) & 0xFF);
|
|
|
|
GBACartSlot.SRAMWrite(addr+2, (val >> 16) & 0xFF);
|
|
|
|
GBACartSlot.SRAMWrite(addr+3, val >> 24);
|
2019-12-08 22:56:22 +00:00
|
|
|
return;
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
//Log(LogLevel::Warn, "unknown arm9 write32 %08X %08X | %08X\n", addr, val, ARM9.R[15]);
|
2016-12-03 00:31:33 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
bool NDS::ARM9GetMemRegion(u32 addr, bool write, MemRegion* region)
|
2018-11-04 22:21:58 +00:00
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
Refactor how save data (including SD cards) is initialized (#1898)
* Remove `FATStorage::Open` and `FATStorage::Close`
- That's what the constructor and destructor are for, respectively
* Add `FATStorage::IsReadOnly`
* Slight cleanup of `FATStorage`
- Make it move-constructible and move-assignable
- Represent the absence of a sync directory with `std::optional`, not an empty string
- Add `FATStorageArgs` for later use
* Refactor `CartHomebrew` to accept an optional `FATStorageArgs`
- `CartHomebrew` uses it to load an SD card image
- Not passing a `FATStorage` directly because we won't know if we need to load the card until we parse the ROM
- Store the `FATStorage` inside a `std::optional` instead of a pointer
- `CartHomebrew::Reset` no longer reloads the SD card; the frontend needs to set it with the `SetSDCard` method
* Close `NANDImage::CurFile` when move-assigning
- Whoops
* Add `Args.h`
- To construct a `NDS` or `DSi` with arguments
- Mostly intended for system files
* Fix incorrect `final` placement
* Refactor how `DSi`'s NAND and SD card are set
- Provide them via a `DSiArgs` argument in the constructor
- Give `DSi_MMCStorage` ownership of the `NANDImage` or `FATStorage` as needed, and expose getters/setters
- Replace `DSi_SDHost::Ports` with a `array<unique_ptr, 2>` to reduce the risk of leaks
- Store `DSi_MMCStorage`'s disk images in a `std::variant`
- The SD card and NAND image are no longer reset in `Reset()`; the frontend will need to do that itself
* Add getters/setters on `DSi` itself for its storage media
* Remove newly-unused `Platform::ConfigEntry`s
* Use `DSi::SetNAND` in the frontend
* Add `EmuThread::NeedToRecreateConsole`
* Document `NDSArgs` and give its fields default values
* Refactor how system files are loaded upon construction
- Pass `NDSArgs&&` into `NDS`'s constructor
- Use `std::array` for the emulator's BIOS images and the built-in FreeBIOS, to simplify copying and comparison
- Initialize the BIOS, firmware, and SD cards from `NDSArgs` or `DSiArgs`
- Add a new default constructor for `NDS` (not `DSi`) that initializes the DS with default system files
- Embed `FirmwareMem::Firmware` directly instead of in a `unique_ptr`
- `SPIHost` now takes a `Firmware&&` that it forwards to `FirmwareMem`
- Add `Firmware` getters/setters plus `const` variants for `NDS`, `Firmware`, and `FirmwareMem`
- Simplify installation of firmware
* Initialize the DSi BIOS in the constructor
- Change `DSi::ARM9iBIOS` and `ARM7iBIOS` to `std::array`
* Update the frontend to reflect the core's changes
* Remove `DSi_SDHost::CloseHandles`
* Pass `nullopt` instead of the empty string when folder sync is off
* Deduplicate ROM extraction logic
- `LoadGBAROM` and `LoadROM` now delegate to `LoadROMData`
- Also use `unique_ptr` instead of `new[]`
* Oops, missed some `get()`'s
* Move `NDS::IsLoadedARM9BIOSBuiltIn` to the header
- So it's likelier to be inlined
- Same for the ARM7 version
* Remove `NDS::SetConsoleType`
* Add `NDS::SetFirmware`
* Move `GBACart::SetupSave` to be `protected`
- It was only ever used inside the class
* Rename `GBACart::LoadSave` to `SetSaveMemory`
- Same for the cart slot
* Declare `GBACartSlot` as a friend of `GBACart::CartCommon`
* Revise `GBACartSlot`'s getters and setters
- Rename `InsertROM` and `LoadROM` to `SetCart`
- Add a `GetCart` method
* Clean up getters and setters for NDS and GBA carts
* Clean up how carts are inserted into the slots
- Remove setters that operate directly on pointers, to simplify error-handling (use ParseROM instead)
- Add overloads for all carts that accept a `const u8*` (to copy the ROM data) and a `unique_ptr<u8[]>` (to move the ROM data)
- Store all ROM and RAM data in `unique_ptr`
- Default-initialize all fields
- Simplify constructors and destructors, inheriting where applicable
* Refactor GBA save data insertion
- Make `SetupSave` private and non-virtual and move its logic to be in `SetSaveMemory`
- Add overloads for setting save data in the constructor
- Update the SRAM completely in `SetSaveMemory`
* Clean up `NDSCart::CartCommon::SetSaveMemory`
- Move its declaration next to the other `SaveMemory` methods
- Move its (empty) implementation to the header
* Add some comments
* Add Utils.cpp and Utils.h
* Rename some functions in Utils for clarity
* Add `GBACart::ParseROM` and `NDSCart::ParseROM` overloads that accept `unique_ptr<u8[]>`
- The `u8*` overloads delegate to these new overloads
- Also move `SetupSave` for both kinds of carts to be private non-virtual methods
* Finalize the `NDSCart` refactor
- Add `NDSCartArgs` to pass to `ParseROM`
- Add SRAM arguments for all retail carts
- Initialize SRAM inside the constructor
- Delegate to other constructors where possible
* Replace `ROMManager::NDSSave` and `GBASave` with `unique_ptr`
* Make both cart slots return the previously-inserted cart in `EjectCart`
- Primarily intended for reusing carts when resetting the console
* Make `NDS::EjectCart` return the old cart
* Initialize both cart slots with the provided ROM (if any)
* Make `NDS::EjectGBACart` return the ejected cart
* Clean up some comments in Args.h
* Rename `ROMManager::LoadBIOS` to `BootToMenu`
- Clarifies the intent
* Add `ROMManager::LoadDLDISDCard`
* Add a doc comment
* Refactor how the `NDS` is created or updated
- Rewrite `CreateConsole` to read from `Config` and load system files, but accept carts as arguments
- Fail without creating an `NDS` if any required system file doesn't load
- Add `UpdateConsole`, which delegates to `CreateConsole` if switching modes or starting the app
- Use `std::variant` to indicate whether a cart should be removed, inserted, or reused
- Load all system files (plus SD cards) in `UpdateConsole`
- Eject the cart and reinsert it into the new console if applicable
* Respect some more `Config` settings in the `Load*` functions
* Remove `InstallNAND` in favor of `LoadNAND`
* Fix some potential bugs in `LoadROMData`
* Oops, forgot to delete the definition of `InstallNAND`
* Add functions to get `FATStorageArgs`
- Not the cards themselves, but to get the arguments you _would_ use to load the cards
* Refactor `ROMManager::LoadROM`
- Load the ROM and save data before trying to initialize the console
* Clean up `ROMManager::Reset` and `BootToMenu`
- Let `EmuThread::UpdateConsole` do the heavy lifting
* Clean up `LoadGBAROM`
* Remove some unused functions
* Set the default DSi BIOS to be broken in `DSiArgs`
* Respect `Config::DSiFullBIOSBoot` when loading DSi BIOS files
* Remove some more unused functions
* Remove redundant `virtual` specifiers
* Refactor `NDSCart::CartCommon::Type()` to return a member instead of a constant
- One less virtual dispatch
- The cart type is read in `NDSCartSlot::DoSavestate`, which is a path downstream (due to rewinding)
* Remove a hash that I computed for debugging purposes
* Make `ByteSwap` `constexpr`
* Remove an unused `#include`
* Remove unnecessary functions from the NDS carts
- Mostly overrides that added nothing
* Default-initialize all NDSCart fields
* Make `GBACart::Type()` not rely on virtual dispatch
- `GBACartSlot::DoSavestate` calls it, and savestates can be a hot path downstream
* Don't forget to reset the base class in `CartGameSolarSensor::Reset()`
* Remove redundant `virtual` specifiers
* Default-initialize some fields in `GBACart`
* Fix ROMs not loading from archives in the frontend
- Whoops
* Change how the `Firmware` member is declared
* Forgot an include in Utils.cpp
* Rename `FirmwareMem::Firmware` to `FirmwareData` to fix a build error on Linux
- One of these days I'll convince you people to let me use `camelCaseMemberNames`
* Add `override` to places in `DSi_MMCStorage` that warrant it
* Fix firmware saving on the frontend
- Remove `GetConfigString` and `ConfigEntry::WifiSettingsPath` while I'm at it
* Add a non-const `GetNAND()`
2023-12-04 16:57:22 +00:00
|
|
|
region->Mem = &ARM9BIOS[0];
|
2018-11-04 22:21:58 +00:00
|
|
|
region->Mask = 0xFFF;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
region->Mem = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-12-03 00:31:33 +00:00
|
|
|
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
u8 NDS::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?
|
2023-11-28 22:16:41 +00:00
|
|
|
if (ARM7.R[15] >= 0x00004000)
|
2018-12-08 21:33:41 +00:00
|
|
|
return 0xFF;
|
2023-11-28 22:16:41 +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:
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDS::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;
|
2023-11-28 22:16:41 +00:00
|
|
|
if (addr & 0x1) return Wifi.Read(addr-1) >> 8;
|
|
|
|
return Wifi.Read(addr) & 0xFF;
|
2021-04-24 22:48:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2016-12-05 22:17:03 +00:00
|
|
|
case 0x06000000:
|
|
|
|
case 0x06800000:
|
2023-11-28 22:16: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
|
2023-11-28 22:16:41 +00:00
|
|
|
if (addr & 0x1) return GBACartSlot.ROMRead(addr-1) >> 8;
|
|
|
|
return GBACartSlot.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
|
2023-11-28 22:16:41 +00:00
|
|
|
return GBACartSlot.SRAMRead(addr);
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
Log(LogLevel::Debug, "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
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
u16 NDS::ARM7Read16(u32 addr)
|
2016-12-03 00:31:33 +00:00
|
|
|
{
|
2022-10-22 11:11:57 +00:00
|
|
|
addr &= ~0x1;
|
|
|
|
|
2016-12-03 00:31:33 +00:00
|
|
|
if (addr < 0x00004000)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
if (ARM7.R[15] >= 0x00004000)
|
2018-12-08 21:33:41 +00:00
|
|
|
return 0xFFFF;
|
2023-11-28 22:16:41 +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:
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDS::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;
|
2023-11-28 22:16: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:
|
2023-11-28 22:16: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
|
2023-11-28 22:16:41 +00:00
|
|
|
return GBACartSlot.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
|
2023-11-28 22:16:41 +00:00
|
|
|
return GBACartSlot.SRAMRead(addr) |
|
|
|
|
(GBACartSlot.SRAMRead(addr+1) << 8);
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
Log(LogLevel::Debug, "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
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
u32 NDS::ARM7Read32(u32 addr)
|
2016-11-03 00:38:58 +00:00
|
|
|
{
|
2022-10-22 11:11:57 +00:00
|
|
|
addr &= ~0x3;
|
|
|
|
|
2016-11-03 00:38:58 +00:00
|
|
|
if (addr < 0x00004000)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
if (ARM7.R[15] >= 0x00004000)
|
2018-12-08 21:33:41 +00:00
|
|
|
return 0xFFFFFFFF;
|
2023-11-28 22:16:41 +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:
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDS::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;
|
2023-11-28 22:16: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:
|
2023-11-28 22:16: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
|
2023-11-28 22:16:41 +00:00
|
|
|
return GBACartSlot.ROMRead(addr) |
|
|
|
|
(GBACartSlot.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
|
2023-11-28 22:16:41 +00:00
|
|
|
return GBACartSlot.SRAMRead(addr) |
|
|
|
|
(GBACartSlot.SRAMRead(addr+1) << 8) |
|
|
|
|
(GBACartSlot.SRAMRead(addr+2) << 16) |
|
|
|
|
(GBACartSlot.SRAMRead(addr+3) << 24);
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
2016-12-05 16:08:24 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
//Log(LogLevel::Warn, "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
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::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:
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_MainRAM>(addr);
|
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
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_SharedWRAM>(addr);
|
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
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr);
|
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:
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr);
|
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:
|
2023-11-28 22:16:41 +00:00
|
|
|
NDS::ARM7IOWrite8(addr, val);
|
2018-12-08 21:33:41 +00:00
|
|
|
return;
|
2016-12-05 22:17:03 +00:00
|
|
|
|
|
|
|
case 0x06000000:
|
|
|
|
case 0x06800000:
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_VWRAM>(addr);
|
|
|
|
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
|
2023-11-28 22:16:41 +00:00
|
|
|
GBACartSlot.SRAMWrite(addr, val);
|
2019-12-08 22:56:22 +00:00
|
|
|
return;
|
2016-12-03 12:42:27 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
//if (ARM7.R[15] > 0x00002F30) // ARM7 BIOS bug
|
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)
|
2023-11-28 22:16:41 +00:00
|
|
|
Log(LogLevel::Debug, "unknown arm7 write8 %08X %02X @ %08X\n", addr, val, ARM7.R[15]);
|
2016-12-03 00:31:33 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::ARM7Write16(u32 addr, u16 val)
|
2017-06-12 23:01:46 +00:00
|
|
|
{
|
2022-10-22 11:11:57 +00:00
|
|
|
addr &= ~0x1;
|
|
|
|
|
2016-12-03 12:42:27 +00:00
|
|
|
switch (addr & 0xFF800000)
|
|
|
|
{
|
|
|
|
case 0x02000000:
|
2017-02-01 20:35:00 +00:00
|
|
|
case 0x02800000:
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_MainRAM>(addr);
|
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
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_SharedWRAM>(addr);
|
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
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr);
|
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:
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr);
|
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:
|
2023-11-28 22:16:41 +00:00
|
|
|
NDS::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;
|
2023-11-28 22:16:41 +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:
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_VWRAM>(addr);
|
|
|
|
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
|
2023-11-28 22:16:41 +00:00
|
|
|
GBACartSlot.ROMWrite(addr, val);
|
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:
|
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
|
2023-11-28 22:16:41 +00:00
|
|
|
GBACartSlot.SRAMWrite(addr, val & 0xFF);
|
|
|
|
GBACartSlot.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)
|
2023-11-28 22:16:41 +00:00
|
|
|
Log(LogLevel::Debug, "unknown arm7 write16 %08X %04X @ %08X\n", addr, val, ARM7.R[15]);
|
2016-05-16 15:48:40 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::ARM7Write32(u32 addr, u32 val)
|
2016-05-16 15:48:40 +00:00
|
|
|
{
|
2022-10-22 11:11:57 +00:00
|
|
|
addr &= ~0x3;
|
|
|
|
|
2016-12-03 12:42:27 +00:00
|
|
|
switch (addr & 0xFF800000)
|
|
|
|
{
|
|
|
|
case 0x02000000:
|
2017-02-01 20:35:00 +00:00
|
|
|
case 0x02800000:
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_MainRAM>(addr);
|
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
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_SharedWRAM>(addr);
|
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
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr);
|
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:
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_WRAM7>(addr);
|
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:
|
2023-11-28 22:16:41 +00:00
|
|
|
NDS::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;
|
2023-11-28 22:16:41 +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:
|
2023-11-28 22:16:41 +00:00
|
|
|
JIT.CheckAndInvalidate<1, ARMJIT_Memory::memregion_VWRAM>(addr);
|
|
|
|
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
|
2023-11-28 22:16:41 +00:00
|
|
|
GBACartSlot.ROMWrite(addr, val & 0xFFFF);
|
|
|
|
GBACartSlot.ROMWrite(addr+2, val >> 16);
|
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:
|
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
|
2023-11-28 22:16:41 +00:00
|
|
|
GBACartSlot.SRAMWrite(addr, val & 0xFF);
|
|
|
|
GBACartSlot.SRAMWrite(addr+1, (val >> 8) & 0xFF);
|
|
|
|
GBACartSlot.SRAMWrite(addr+2, (val >> 16) & 0xFF);
|
|
|
|
GBACartSlot.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)
|
2023-11-28 22:16:41 +00:00
|
|
|
Log(LogLevel::Debug, "unknown arm7 write32 %08X %08X @ %08X\n", addr, val, ARM7.R[15]);
|
2016-05-16 15:48:40 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
bool NDS::ARM7GetMemRegion(u32 addr, bool write, MemRegion* region)
|
2018-11-04 22:21:58 +00:00
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
if (ARM7.R[15] < 0x4000 && (addr >= ARM7BIOSProt || ARM7.R[15] < ARM7BIOSProt))
|
2018-11-04 22:21:58 +00:00
|
|
|
{
|
Refactor how save data (including SD cards) is initialized (#1898)
* Remove `FATStorage::Open` and `FATStorage::Close`
- That's what the constructor and destructor are for, respectively
* Add `FATStorage::IsReadOnly`
* Slight cleanup of `FATStorage`
- Make it move-constructible and move-assignable
- Represent the absence of a sync directory with `std::optional`, not an empty string
- Add `FATStorageArgs` for later use
* Refactor `CartHomebrew` to accept an optional `FATStorageArgs`
- `CartHomebrew` uses it to load an SD card image
- Not passing a `FATStorage` directly because we won't know if we need to load the card until we parse the ROM
- Store the `FATStorage` inside a `std::optional` instead of a pointer
- `CartHomebrew::Reset` no longer reloads the SD card; the frontend needs to set it with the `SetSDCard` method
* Close `NANDImage::CurFile` when move-assigning
- Whoops
* Add `Args.h`
- To construct a `NDS` or `DSi` with arguments
- Mostly intended for system files
* Fix incorrect `final` placement
* Refactor how `DSi`'s NAND and SD card are set
- Provide them via a `DSiArgs` argument in the constructor
- Give `DSi_MMCStorage` ownership of the `NANDImage` or `FATStorage` as needed, and expose getters/setters
- Replace `DSi_SDHost::Ports` with a `array<unique_ptr, 2>` to reduce the risk of leaks
- Store `DSi_MMCStorage`'s disk images in a `std::variant`
- The SD card and NAND image are no longer reset in `Reset()`; the frontend will need to do that itself
* Add getters/setters on `DSi` itself for its storage media
* Remove newly-unused `Platform::ConfigEntry`s
* Use `DSi::SetNAND` in the frontend
* Add `EmuThread::NeedToRecreateConsole`
* Document `NDSArgs` and give its fields default values
* Refactor how system files are loaded upon construction
- Pass `NDSArgs&&` into `NDS`'s constructor
- Use `std::array` for the emulator's BIOS images and the built-in FreeBIOS, to simplify copying and comparison
- Initialize the BIOS, firmware, and SD cards from `NDSArgs` or `DSiArgs`
- Add a new default constructor for `NDS` (not `DSi`) that initializes the DS with default system files
- Embed `FirmwareMem::Firmware` directly instead of in a `unique_ptr`
- `SPIHost` now takes a `Firmware&&` that it forwards to `FirmwareMem`
- Add `Firmware` getters/setters plus `const` variants for `NDS`, `Firmware`, and `FirmwareMem`
- Simplify installation of firmware
* Initialize the DSi BIOS in the constructor
- Change `DSi::ARM9iBIOS` and `ARM7iBIOS` to `std::array`
* Update the frontend to reflect the core's changes
* Remove `DSi_SDHost::CloseHandles`
* Pass `nullopt` instead of the empty string when folder sync is off
* Deduplicate ROM extraction logic
- `LoadGBAROM` and `LoadROM` now delegate to `LoadROMData`
- Also use `unique_ptr` instead of `new[]`
* Oops, missed some `get()`'s
* Move `NDS::IsLoadedARM9BIOSBuiltIn` to the header
- So it's likelier to be inlined
- Same for the ARM7 version
* Remove `NDS::SetConsoleType`
* Add `NDS::SetFirmware`
* Move `GBACart::SetupSave` to be `protected`
- It was only ever used inside the class
* Rename `GBACart::LoadSave` to `SetSaveMemory`
- Same for the cart slot
* Declare `GBACartSlot` as a friend of `GBACart::CartCommon`
* Revise `GBACartSlot`'s getters and setters
- Rename `InsertROM` and `LoadROM` to `SetCart`
- Add a `GetCart` method
* Clean up getters and setters for NDS and GBA carts
* Clean up how carts are inserted into the slots
- Remove setters that operate directly on pointers, to simplify error-handling (use ParseROM instead)
- Add overloads for all carts that accept a `const u8*` (to copy the ROM data) and a `unique_ptr<u8[]>` (to move the ROM data)
- Store all ROM and RAM data in `unique_ptr`
- Default-initialize all fields
- Simplify constructors and destructors, inheriting where applicable
* Refactor GBA save data insertion
- Make `SetupSave` private and non-virtual and move its logic to be in `SetSaveMemory`
- Add overloads for setting save data in the constructor
- Update the SRAM completely in `SetSaveMemory`
* Clean up `NDSCart::CartCommon::SetSaveMemory`
- Move its declaration next to the other `SaveMemory` methods
- Move its (empty) implementation to the header
* Add some comments
* Add Utils.cpp and Utils.h
* Rename some functions in Utils for clarity
* Add `GBACart::ParseROM` and `NDSCart::ParseROM` overloads that accept `unique_ptr<u8[]>`
- The `u8*` overloads delegate to these new overloads
- Also move `SetupSave` for both kinds of carts to be private non-virtual methods
* Finalize the `NDSCart` refactor
- Add `NDSCartArgs` to pass to `ParseROM`
- Add SRAM arguments for all retail carts
- Initialize SRAM inside the constructor
- Delegate to other constructors where possible
* Replace `ROMManager::NDSSave` and `GBASave` with `unique_ptr`
* Make both cart slots return the previously-inserted cart in `EjectCart`
- Primarily intended for reusing carts when resetting the console
* Make `NDS::EjectCart` return the old cart
* Initialize both cart slots with the provided ROM (if any)
* Make `NDS::EjectGBACart` return the ejected cart
* Clean up some comments in Args.h
* Rename `ROMManager::LoadBIOS` to `BootToMenu`
- Clarifies the intent
* Add `ROMManager::LoadDLDISDCard`
* Add a doc comment
* Refactor how the `NDS` is created or updated
- Rewrite `CreateConsole` to read from `Config` and load system files, but accept carts as arguments
- Fail without creating an `NDS` if any required system file doesn't load
- Add `UpdateConsole`, which delegates to `CreateConsole` if switching modes or starting the app
- Use `std::variant` to indicate whether a cart should be removed, inserted, or reused
- Load all system files (plus SD cards) in `UpdateConsole`
- Eject the cart and reinsert it into the new console if applicable
* Respect some more `Config` settings in the `Load*` functions
* Remove `InstallNAND` in favor of `LoadNAND`
* Fix some potential bugs in `LoadROMData`
* Oops, forgot to delete the definition of `InstallNAND`
* Add functions to get `FATStorageArgs`
- Not the cards themselves, but to get the arguments you _would_ use to load the cards
* Refactor `ROMManager::LoadROM`
- Load the ROM and save data before trying to initialize the console
* Clean up `ROMManager::Reset` and `BootToMenu`
- Let `EmuThread::UpdateConsole` do the heavy lifting
* Clean up `LoadGBAROM`
* Remove some unused functions
* Set the default DSi BIOS to be broken in `DSiArgs`
* Respect `Config::DSiFullBIOSBoot` when loading DSi BIOS files
* Remove some more unused functions
* Remove redundant `virtual` specifiers
* Refactor `NDSCart::CartCommon::Type()` to return a member instead of a constant
- One less virtual dispatch
- The cart type is read in `NDSCartSlot::DoSavestate`, which is a path downstream (due to rewinding)
* Remove a hash that I computed for debugging purposes
* Make `ByteSwap` `constexpr`
* Remove an unused `#include`
* Remove unnecessary functions from the NDS carts
- Mostly overrides that added nothing
* Default-initialize all NDSCart fields
* Make `GBACart::Type()` not rely on virtual dispatch
- `GBACartSlot::DoSavestate` calls it, and savestates can be a hot path downstream
* Don't forget to reset the base class in `CartGameSolarSensor::Reset()`
* Remove redundant `virtual` specifiers
* Default-initialize some fields in `GBACart`
* Fix ROMs not loading from archives in the frontend
- Whoops
* Change how the `Firmware` member is declared
* Forgot an include in Utils.cpp
* Rename `FirmwareMem::Firmware` to `FirmwareData` to fix a build error on Linux
- One of these days I'll convince you people to let me use `camelCaseMemberNames`
* Add `override` to places in `DSi_MMCStorage` that warrant it
* Fix firmware saving on the frontend
- Remove `GetConfigString` and `ConfigEntry::WifiSettingsPath` while I'm at it
* Add a non-const `GetNAND()`
2023-12-04 16:57:22 +00:00
|
|
|
region->Mem = &ARM7BIOS[0];
|
2018-11-04 22:21:58 +00:00
|
|
|
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;
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
u8 NDS::ARM9IORead8(u32 addr)
|
2017-01-17 01:29:25 +00:00
|
|
|
{
|
|
|
|
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;
|
2023-10-30 17:37:49 +00:00
|
|
|
case 0x04000132: return KeyCnt[0] & 0xFF;
|
|
|
|
case 0x04000133: return KeyCnt[0] >> 8;
|
2017-04-23 23:30:30 +00:00
|
|
|
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x040001A2:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.ReadSPIData();
|
2021-04-24 22:48:02 +00:00
|
|
|
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)))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(0);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
|
|
|
case 0x040001A9:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(1);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
|
|
|
case 0x040001AA:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(2);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
|
|
|
case 0x040001AB:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(3);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
|
|
|
case 0x040001AC:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(4);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
|
|
|
case 0x040001AD:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(5);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
|
|
|
case 0x040001AE:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(6);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
|
|
|
case 0x040001AF:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(7);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
2017-03-30 23:50:01 +00:00
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000208: return IME[0];
|
|
|
|
|
2023-11-28 22:16:41 +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;
|
2023-11-28 22:16:41 +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)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
return GPU.GPU2D_A.Read8(addr);
|
2017-01-18 03:03:19 +00:00
|
|
|
}
|
|
|
|
if (addr >= 0x04001000 && addr < 0x04001060)
|
|
|
|
{
|
2023-11-28 22:16:41 +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)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
return GPU.GPU3D.Read8(addr);
|
2017-02-07 22:31:21 +00:00
|
|
|
}
|
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)
|
2023-11-28 22:16:41 +00:00
|
|
|
Log(LogLevel::Debug, "unknown ARM9 IO read8 %08X %08X\n", addr, ARM9.R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
u16 NDS::ARM9IORead16(u32 addr)
|
2017-01-17 01:29:25 +00:00
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x04000004: return GPU.DispStat[0];
|
|
|
|
case 0x04000006: return GPU.VCount;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x04000060: return GPU.GPU3D.Read16(addr);
|
2017-03-04 13:47:20 +00:00
|
|
|
case 0x04000064:
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x04000066: return GPU.GPU2D_A.Read16(addr);
|
2017-01-31 23:24:36 +00:00
|
|
|
|
2023-11-28 22:16:41 +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-31 16:34:17 +00:00
|
|
|
|
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;
|
2023-10-30 17:37:49 +00:00
|
|
|
case 0x04000132: return KeyCnt[0];
|
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)))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetSPICnt();
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
|
|
|
case 0x040001A2:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.ReadSPIData();
|
2021-04-24 22:48:02 +00:00
|
|
|
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)))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(0) |
|
|
|
|
(NDSCartSlot.GetROMCommand(1) << 8);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
|
|
|
case 0x040001AA:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(2) |
|
|
|
|
(NDSCartSlot.GetROMCommand(3) << 8);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
|
|
|
case 0x040001AC:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(4) |
|
|
|
|
(NDSCartSlot.GetROMCommand(5) << 8);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
|
|
|
case 0x040001AE:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(6) |
|
|
|
|
(NDSCartSlot.GetROMCommand(7) << 8);
|
2021-04-24 22:48:02 +00:00
|
|
|
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
|
|
|
|
2023-11-28 22:16:41 +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-03-04 13:47:20 +00:00
|
|
|
|
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
|
|
|
{
|
2023-11-28 22:16:41 +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
|
|
|
{
|
2023-11-28 22:16:41 +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)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
return GPU.GPU3D.Read16(addr);
|
2017-02-07 22:31:21 +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)
|
2023-11-28 22:16:41 +00:00
|
|
|
Log(LogLevel::Debug, "unknown ARM9 IO read16 %08X %08X\n", addr, ARM9.R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
u32 NDS::ARM9IORead32(u32 addr)
|
2017-01-17 01:29:25 +00:00
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x04000004: return GPU.DispStat[0] | (GPU.VCount << 16);
|
|
|
|
|
|
|
|
case 0x04000060: return GPU.GPU3D.Read32(addr);
|
|
|
|
case 0x04000064: return GPU.GPU2D_A.Read32(addr);
|
|
|
|
|
|
|
|
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;
|
2017-01-18 00:33:06 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
2023-10-30 17:37:49 +00:00
|
|
|
case 0x04000130: LagFrameFlag = false; return (KeyInput & 0xFFFF) | (KeyCnt[0] << 16);
|
2017-06-04 20:34:31 +00:00
|
|
|
|
2018-04-24 20:31:52 +00:00
|
|
|
case 0x04000180: return IPCSync9;
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x04000184: return NDS::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)))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetSPICnt() | (NDSCartSlot.ReadSPIData() << 16);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
|
|
|
case 0x040001A4:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCnt();
|
2021-04-24 22:48:02 +00:00
|
|
|
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)))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(0) |
|
|
|
|
(NDSCartSlot.GetROMCommand(1) << 8) |
|
|
|
|
(NDSCartSlot.GetROMCommand(2) << 16) |
|
|
|
|
(NDSCartSlot.GetROMCommand(3) << 24);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
|
|
|
case 0x040001AC:
|
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(4) |
|
|
|
|
(NDSCartSlot.GetROMCommand(5) << 8) |
|
|
|
|
(NDSCartSlot.GetROMCommand(6) << 16) |
|
|
|
|
(NDSCartSlot.GetROMCommand(7) << 24);
|
2021-04-24 22:48:02 +00:00
|
|
|
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];
|
|
|
|
|
2023-11-28 22:16:41 +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-03-04 13:47:20 +00:00
|
|
|
|
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:
|
2023-11-28 22:16:41 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11))) return NDSCartSlot.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
|
|
|
{
|
2023-11-28 22:16:41 +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
|
|
|
{
|
2023-11-28 22:16:41 +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)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
return GPU.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)
|
2023-11-28 22:16:41 +00:00
|
|
|
Log(LogLevel::Debug, "unknown ARM9 IO read32 %08X %08X\n", addr, ARM9.R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::ARM9IOWrite8(u32 addr, u8 val)
|
2017-01-17 01:29:25 +00:00
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2017-07-23 13:31:09 +00:00
|
|
|
case 0x0400006C:
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x0400006D: GPU.GPU2D_A.Write8(addr, val); return;
|
2017-07-23 13:31:09 +00:00
|
|
|
case 0x0400106C:
|
2023-11-28 22:16:41 +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:
|
2023-10-30 17:37:49 +00:00
|
|
|
KeyCnt[0] = (KeyCnt[0] & 0xFF00) | val;
|
2017-06-04 20:34:31 +00:00
|
|
|
return;
|
|
|
|
case 0x04000133:
|
2023-10-30 17:37:49 +00:00
|
|
|
KeyCnt[0] = (KeyCnt[0] & 0x00FF) | (val << 8);
|
2017-06-04 20:34:31 +00:00
|
|
|
return;
|
|
|
|
|
2021-04-24 22:48:02 +00:00
|
|
|
case 0x04000188:
|
2023-11-28 22:16:41 +00:00
|
|
|
NDS::ARM9IOWrite32(addr, val | (val << 8) | (val << 16) | (val << 24));
|
2021-04-24 22:48:02 +00:00
|
|
|
return;
|
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x040001A0:
|
2017-01-22 19:34:59 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.WriteSPICnt((NDSCartSlot.GetSPICnt() & 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)))
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.WriteSPICnt((NDSCartSlot.GetSPICnt() & 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)))
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.WriteSPIData(val);
|
2020-10-29 20:09:25 +00:00
|
|
|
return;
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x040001A8: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot.SetROMCommand(0, val); return;
|
|
|
|
case 0x040001A9: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot.SetROMCommand(1, val); return;
|
|
|
|
case 0x040001AA: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot.SetROMCommand(2, val); return;
|
|
|
|
case 0x040001AB: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot.SetROMCommand(3, val); return;
|
|
|
|
case 0x040001AC: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot.SetROMCommand(4, val); return;
|
|
|
|
case 0x040001AD: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot.SetROMCommand(5, val); return;
|
|
|
|
case 0x040001AE: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot.SetROMCommand(6, val); return;
|
|
|
|
case 0x040001AF: if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot.SetROMCommand(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
|
|
|
|
2023-11-28 22:16:41 +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;
|
2023-11-28 22:16:41 +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)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
GPU.GPU2D_A.Write8(addr, val);
|
2017-01-18 03:03:19 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (addr >= 0x04001000 && addr < 0x04001060)
|
|
|
|
{
|
2023-11-28 22:16:41 +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)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
GPU.GPU3D.Write8(addr, val);
|
2017-02-07 22:31:21 +00:00
|
|
|
return;
|
|
|
|
}
|
2017-01-18 03:03:19 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
Log(LogLevel::Debug, "unknown ARM9 IO write8 %08X %02X %08X\n", addr, val, ARM9.R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::ARM9IOWrite16(u32 addr, u16 val)
|
2017-01-17 01:29:25 +00:00
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x04000004: GPU.SetDispStat(0, val); return;
|
|
|
|
case 0x04000006: GPU.SetVCount(val); return;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x04000060: GPU.GPU3D.Write16(addr, val); return;
|
2017-01-31 23:24:36 +00:00
|
|
|
|
2017-06-26 09:02:10 +00:00
|
|
|
case 0x04000068:
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x0400006A: GPU.GPU2D_A.Write16(addr, val); return;
|
2017-06-26 09:02:10 +00:00
|
|
|
|
2023-11-28 22:16:41 +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
|
|
|
|
2023-11-28 22:16:41 +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-01-31 16:34:17 +00:00
|
|
|
|
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:
|
2023-10-30 17:37:49 +00:00
|
|
|
KeyCnt[0] = val;
|
2017-06-04 20:34:31 +00:00
|
|
|
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:
|
2023-11-28 22:16:41 +00:00
|
|
|
NDS::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)))
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.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)))
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.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)))
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.SetROMCommand(0, val & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(1, val >> 8);
|
2021-04-24 22:48:02 +00:00
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
case 0x040001AA:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.SetROMCommand(2, val & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(3, val >> 8);
|
2021-04-24 22:48:02 +00:00
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
case 0x040001AC:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.SetROMCommand(4, val & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(5, val >> 8);
|
2021-04-24 22:48:02 +00:00
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
case 0x040001AE:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.SetROMCommand(6, val & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(7, val >> 8);
|
2021-04-24 22:48:02 +00:00
|
|
|
}
|
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:
|
2023-11-28 22:16:41 +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:
|
2023-11-28 22:16:41 +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:
|
2023-11-28 22:16:41 +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:
|
2023-11-28 22:16:41 +00:00
|
|
|
GPU.MapVRAM_FG(6, val & 0xFF);
|
2017-01-17 01:29:25 +00:00
|
|
|
MapSharedWRAM(val >> 8);
|
|
|
|
return;
|
|
|
|
case 0x04000248:
|
2023-11-28 22:16:41 +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;
|
2023-11-28 22:16:41 +00:00
|
|
|
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
|
|
|
{
|
2023-11-28 22:16:41 +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
|
|
|
{
|
2023-11-28 22:16:41 +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)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
GPU.GPU3D.Write16(addr, val);
|
2017-02-01 20:57:25 +00:00
|
|
|
return;
|
|
|
|
}
|
2017-01-18 03:03:19 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
Log(LogLevel::Debug, "unknown ARM9 IO write16 %08X %04X %08X\n", addr, val, ARM9.R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::ARM9IOWrite32(u32 addr, u32 val)
|
2017-01-17 01:29:25 +00:00
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2019-06-20 11:57:14 +00:00
|
|
|
case 0x04000004:
|
2023-11-28 22:16:41 +00:00
|
|
|
GPU.SetDispStat(0, val & 0xFFFF);
|
|
|
|
GPU.SetVCount(val >> 16);
|
2019-06-20 11:57:14 +00:00
|
|
|
return;
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x04000060: GPU.GPU3D.Write32(addr, val); return;
|
2017-06-26 09:02:10 +00:00
|
|
|
case 0x04000064:
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x04000068: GPU.GPU2D_A.Write32(addr, val); return;
|
|
|
|
|
|
|
|
case 0x0400006C: GPU.GPU2D_A.Write16(addr, val&0xFFFF); return;
|
|
|
|
case 0x0400106C: GPU.GPU2D_B.Write16(addr, val&0xFFFF); return;
|
|
|
|
|
|
|
|
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;
|
2017-01-18 00:33:06 +00:00
|
|
|
|
|
|
|
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:
|
2023-10-30 17:37:49 +00:00
|
|
|
KeyCnt[0] = val >> 16;
|
2017-06-04 20:34:31 +00:00
|
|
|
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:
|
2023-11-28 22:16:41 +00:00
|
|
|
NDS::ARM9IOWrite16(addr, val);
|
2018-04-24 20:31:52 +00:00
|
|
|
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)))
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.WriteSPICnt(val & 0xFFFF);
|
|
|
|
NDSCartSlot.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)))
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.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)))
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.SetROMCommand(0, val & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(1, (val >> 8) & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(2, (val >> 16) & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(3, val >> 24);
|
2021-04-24 22:48:02 +00:00
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
case 0x040001AC:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11)))
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.SetROMCommand(4, val & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(5, (val >> 8) & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(6, (val >> 16) & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(7, val >> 24);
|
2021-04-24 22:48:02 +00:00
|
|
|
}
|
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;
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x04000214: IF[0] &= ~val; GPU.GPU3D.CheckFIFOIRQ(); UpdateIRQ(0); return;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
|
|
|
case 0x04000240:
|
2023-11-28 22:16:41 +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:
|
2023-11-28 22:16:41 +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:
|
2023-11-28 22:16:41 +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;
|
2023-11-28 22:16:41 +00:00
|
|
|
GPU.SetPowerCnt(PowerControl9);
|
2017-03-23 16:14:48 +00:00
|
|
|
return;
|
2020-09-03 18:28:07 +00:00
|
|
|
|
|
|
|
case 0x04100010:
|
2023-11-28 22:16:41 +00:00
|
|
|
if (!(ExMemCnt[0] & (1<<11))) NDSCartSlot.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;
|
|
|
|
}
|
2023-03-23 17:04:38 +00:00
|
|
|
Log(LogLevel::Debug, "%s", output);
|
2021-05-27 10:15:16 +00:00
|
|
|
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)
|
2023-03-23 17:04:38 +00:00
|
|
|
Log(LogLevel::Debug, "\n");
|
2021-05-27 10:15:16 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NO$GBA debug register "Char Out"
|
2023-03-23 17:04:38 +00:00
|
|
|
case 0x04FFFA1C: Log(LogLevel::Debug, "%c", val & 0xFF); return;
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
2017-01-18 03:03:19 +00:00
|
|
|
if (addr >= 0x04000000 && addr < 0x04000060)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
GPU.GPU2D_A.Write32(addr, val);
|
2017-01-18 03:03:19 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (addr >= 0x04001000 && addr < 0x04001060)
|
|
|
|
{
|
2023-11-28 22:16:41 +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)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
GPU.GPU3D.Write32(addr, val);
|
2017-01-31 17:41:31 +00:00
|
|
|
return;
|
|
|
|
}
|
2017-01-18 03:03:19 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
Log(LogLevel::Debug, "unknown ARM9 IO write32 %08X %08X %08X\n", addr, val, ARM9.R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
u8 NDS::ARM7IORead8(u32 addr)
|
2017-01-17 01:29:25 +00:00
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2017-04-23 23:30:30 +00:00
|
|
|
case 0x04000130: return KeyInput & 0xFF;
|
|
|
|
case 0x04000131: return (KeyInput >> 8) & 0xFF;
|
2023-10-30 17:37:49 +00:00
|
|
|
case 0x04000132: return KeyCnt[1] & 0xFF;
|
|
|
|
case 0x04000133: return KeyCnt[1] >> 8;
|
2017-06-04 20:34:31 +00:00
|
|
|
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;
|
|
|
|
|
2023-11-28 22:16:41 +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))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.ReadSPIData();
|
2021-04-24 22:48:02 +00:00
|
|
|
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))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(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))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(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))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(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))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(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))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(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))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(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))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(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))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(7);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
2017-03-30 23:50:01 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x040001C2: return SPI.ReadData();
|
2017-01-17 01:29:25 +00:00
|
|
|
|
|
|
|
case 0x04000208: return IME[1];
|
|
|
|
|
2023-11-28 22:16:41 +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)
|
|
|
|
{
|
2023-11-28 22:16:41 +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)
|
2023-11-28 22:16:41 +00:00
|
|
|
Log(LogLevel::Debug, "unknown ARM7 IO read8 %08X %08X\n", addr, ARM7.R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
u16 NDS::ARM7IORead16(u32 addr)
|
2017-01-17 01:29:25 +00:00
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x04000004: return GPU.DispStat[1];
|
|
|
|
case 0x04000006: return GPU.VCount;
|
|
|
|
|
|
|
|
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 16:34:17 +00:00
|
|
|
|
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;
|
2023-10-30 17:37:49 +00:00
|
|
|
case 0x04000132: return KeyCnt[1];
|
2017-06-04 20:34:31 +00:00
|
|
|
case 0x04000134: return RCnt;
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x04000136: return KeyInput >> 16;
|
|
|
|
|
2023-11-28 22:16:41 +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;
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x040001A0: if (ExMemCnt[0] & (1<<11)) return NDSCartSlot.GetSPICnt(); return 0;
|
|
|
|
case 0x040001A2: if (ExMemCnt[0] & (1<<11)) return NDSCartSlot.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))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(0) |
|
|
|
|
(NDSCartSlot.GetROMCommand(1) << 8);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
|
|
|
case 0x040001AA:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(2) |
|
|
|
|
(NDSCartSlot.GetROMCommand(3) << 8);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
|
|
|
case 0x040001AC:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(4) |
|
|
|
|
(NDSCartSlot.GetROMCommand(5) << 8);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
|
|
|
case 0x040001AE:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(6) |
|
|
|
|
(NDSCartSlot.GetROMCommand(7) << 8);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
2017-03-30 23:50:01 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x040001C0: return SPI.ReadCnt();
|
|
|
|
case 0x040001C2: return SPI.ReadData();
|
2017-01-17 01:29:25 +00:00
|
|
|
|
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)
|
|
|
|
{
|
2023-11-28 22:16:41 +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)
|
2023-11-28 22:16:41 +00:00
|
|
|
Log(LogLevel::Debug, "unknown ARM7 IO read16 %08X %08X\n", addr, ARM7.R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
u32 NDS::ARM7IORead32(u32 addr)
|
2017-01-17 01:29:25 +00:00
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x04000004: return GPU.DispStat[1] | (GPU.VCount << 16);
|
|
|
|
|
|
|
|
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-18 00:33:06 +00:00
|
|
|
|
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
|
|
|
|
2023-10-30 17:37:49 +00:00
|
|
|
case 0x04000130: return (KeyInput & 0xFFFF) | (KeyCnt[1] << 16);
|
|
|
|
case 0x04000134: return RCnt | (KeyInput & 0xFFFF0000);
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x04000138: return RTC.Read();
|
2017-06-04 20:34:31 +00:00
|
|
|
|
2018-04-24 20:31:52 +00:00
|
|
|
case 0x04000180: return IPCSync7;
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x04000184: return NDS::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))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetSPICnt() | (NDSCartSlot.ReadSPIData() << 16);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
|
|
|
case 0x040001A4:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCnt();
|
2021-04-24 22:48:02 +00:00
|
|
|
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))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(0) |
|
|
|
|
(NDSCartSlot.GetROMCommand(1) << 8) |
|
|
|
|
(NDSCartSlot.GetROMCommand(2) << 16) |
|
|
|
|
(NDSCartSlot.GetROMCommand(3) << 24);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
|
|
|
case 0x040001AC:
|
|
|
|
if (ExMemCnt[0] & (1<<11))
|
2023-11-28 22:16:41 +00:00
|
|
|
return NDSCartSlot.GetROMCommand(4) |
|
|
|
|
(NDSCartSlot.GetROMCommand(5) << 8) |
|
|
|
|
(NDSCartSlot.GetROMCommand(6) << 16) |
|
|
|
|
(NDSCartSlot.GetROMCommand(7) << 24);
|
2021-04-24 22:48:02 +00:00
|
|
|
return 0;
|
2017-03-30 23:50:01 +00:00
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x040001C0:
|
2023-11-28 22:16:41 +00:00
|
|
|
return SPI.ReadCnt() | (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:
|
2023-11-28 22:16:41 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11)) return NDSCartSlot.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)
|
|
|
|
{
|
2023-11-28 22:16:41 +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)
|
2023-11-28 22:16:41 +00:00
|
|
|
Log(LogLevel::Debug, "unknown ARM7 IO read32 %08X %08X\n", addr, ARM7.R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::ARM7IOWrite8(u32 addr, u8 val)
|
2017-01-17 01:29:25 +00:00
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2017-06-04 20:34:31 +00:00
|
|
|
case 0x04000132:
|
2023-10-30 17:37:49 +00:00
|
|
|
KeyCnt[1] = (KeyCnt[1] & 0xFF00) | val;
|
2017-06-04 20:34:31 +00:00
|
|
|
return;
|
|
|
|
case 0x04000133:
|
2023-10-30 17:37:49 +00:00
|
|
|
KeyCnt[1] = (KeyCnt[1] & 0x00FF) | (val << 8);
|
2017-06-04 20:34:31 +00:00
|
|
|
return;
|
|
|
|
case 0x04000134:
|
|
|
|
RCnt = (RCnt & 0xFF00) | val;
|
|
|
|
return;
|
|
|
|
case 0x04000135:
|
|
|
|
RCnt = (RCnt & 0x00FF) | (val << 8);
|
|
|
|
return;
|
|
|
|
|
2023-11-28 22:16:41 +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:
|
2023-11-28 22:16:41 +00:00
|
|
|
NDS::ARM7IOWrite32(addr, val | (val << 8) | (val << 16) | (val << 24));
|
2020-10-29 20:09:25 +00:00
|
|
|
return;
|
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x040001A0:
|
2017-01-22 19:34:59 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.WriteSPICnt((NDSCartSlot.GetSPICnt() & 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))
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.WriteSPICnt((NDSCartSlot.GetSPICnt() & 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))
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.WriteSPIData(val);
|
2017-01-31 02:54:51 +00:00
|
|
|
return;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x040001A8: if (ExMemCnt[0] & (1<<11)) NDSCartSlot.SetROMCommand(0, val); return;
|
|
|
|
case 0x040001A9: if (ExMemCnt[0] & (1<<11)) NDSCartSlot.SetROMCommand(1, val); return;
|
|
|
|
case 0x040001AA: if (ExMemCnt[0] & (1<<11)) NDSCartSlot.SetROMCommand(2, val); return;
|
|
|
|
case 0x040001AB: if (ExMemCnt[0] & (1<<11)) NDSCartSlot.SetROMCommand(3, val); return;
|
|
|
|
case 0x040001AC: if (ExMemCnt[0] & (1<<11)) NDSCartSlot.SetROMCommand(4, val); return;
|
|
|
|
case 0x040001AD: if (ExMemCnt[0] & (1<<11)) NDSCartSlot.SetROMCommand(5, val); return;
|
|
|
|
case 0x040001AE: if (ExMemCnt[0] & (1<<11)) NDSCartSlot.SetROMCommand(6, val); return;
|
|
|
|
case 0x040001AF: if (ExMemCnt[0] & (1<<11)) NDSCartSlot.SetROMCommand(7, val); return;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
|
|
|
case 0x040001C2:
|
2023-11-28 22:16:41 +00:00
|
|
|
SPI.WriteData(val);
|
2017-01-17 01:29:25 +00:00
|
|
|
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:
|
2023-11-28 22:16:41 +00:00
|
|
|
if (ARM7.R[15] >= 0x4000)
|
2017-01-18 01:20:45 +00:00
|
|
|
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;
|
2023-08-18 20:50:57 +00:00
|
|
|
if (val == 0x40) Stop(StopReason::GBAModeNotSupported);
|
2023-11-28 22:16:41 +00:00
|
|
|
else if (val == 0x80) ARM7.Halt(1);
|
2018-12-14 01:36:57 +00:00
|
|
|
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)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
SPU.Write8(addr, val);
|
2017-01-20 00:18:30 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
Log(LogLevel::Debug, "unknown ARM7 IO write8 %08X %02X %08X\n", addr, val, ARM7.R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::ARM7IOWrite16(u32 addr, u16 val)
|
2017-01-17 01:29:25 +00:00
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x04000004: GPU.SetDispStat(1, val); return;
|
|
|
|
case 0x04000006: GPU.SetVCount(val); return;
|
|
|
|
|
|
|
|
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-31 16:34:17 +00:00
|
|
|
|
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;
|
|
|
|
|
2023-10-30 17:37:49 +00:00
|
|
|
case 0x04000132: KeyCnt[1] = val; return;
|
2017-06-04 20:34:31 +00:00
|
|
|
case 0x04000134: RCnt = val; return;
|
2017-01-17 01:29:25 +00:00
|
|
|
|
2023-11-28 22:16:41 +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:
|
2023-11-28 22:16:41 +00:00
|
|
|
NDS::ARM7IOWrite32(addr, val | (val << 16));
|
2020-10-29 20:09:25 +00:00
|
|
|
return;
|
|
|
|
|
2017-01-17 01:29:25 +00:00
|
|
|
case 0x040001A0:
|
2017-01-22 19:34:59 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11))
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.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))
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.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))
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.SetROMCommand(0, val & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(1, val >> 8);
|
2021-04-24 22:48:02 +00:00
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
case 0x040001AA:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.SetROMCommand(2, val & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(3, val >> 8);
|
2021-04-24 22:48:02 +00:00
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
case 0x040001AC:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.SetROMCommand(4, val & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(5, val >> 8);
|
2021-04-24 22:48:02 +00:00
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
case 0x040001AE:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.SetROMCommand(6, val & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(7, val >> 8);
|
2021-04-24 22:48:02 +00:00
|
|
|
}
|
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:
|
2023-11-28 22:16:41 +00:00
|
|
|
SPI.WriteCnt(val);
|
2017-01-17 01:29:25 +00:00
|
|
|
return;
|
|
|
|
case 0x040001C2:
|
2023-11-28 22:16:41 +00:00
|
|
|
SPI.WriteData(val & 0xFF);
|
2017-01-17 01:29:25 +00:00
|
|
|
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:
|
2023-11-28 22:16:41 +00:00
|
|
|
if (ARM7.R[15] >= 0x4000)
|
2017-01-18 01:20:45 +00:00
|
|
|
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;
|
2023-11-28 22:16:41 +00:00
|
|
|
SPU.SetPowerCnt(val & 0x0001);
|
|
|
|
Wifi.SetPowerCnt(val & 0x0002);
|
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 (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)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
SPU.Write16(addr, val);
|
2017-01-20 00:18:30 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
Log(LogLevel::Debug, "unknown ARM7 IO write16 %08X %04X %08X\n", addr, val, ARM7.R[15]);
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
void NDS::ARM7IOWrite32(u32 addr, u32 val)
|
2017-01-17 01:29:25 +00:00
|
|
|
{
|
|
|
|
switch (addr)
|
|
|
|
{
|
2019-06-20 11:57:14 +00:00
|
|
|
case 0x04000004:
|
2023-11-28 22:16:41 +00:00
|
|
|
GPU.SetDispStat(1, val & 0xFFFF);
|
|
|
|
GPU.SetVCount(val >> 16);
|
|
|
|
return;
|
|
|
|
|
|
|
|
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;
|
|
|
|
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;
|
|
|
|
|
2023-10-30 17:37:49 +00:00
|
|
|
case 0x04000130: KeyCnt[1] = val >> 16; return;
|
2017-06-04 20:34:31 +00:00
|
|
|
case 0x04000134: RCnt = val & 0xFFFF; return;
|
2023-11-28 22:16:41 +00:00
|
|
|
case 0x04000138: RTC.Write(val & 0xFFFF, false); return;
|
2017-06-04 20:34:31 +00:00
|
|
|
|
2018-04-24 20:31:52 +00:00
|
|
|
case 0x04000180:
|
2020-10-25 17:14:40 +00:00
|
|
|
case 0x04000184:
|
2023-11-28 22:16:41 +00:00
|
|
|
NDS::ARM7IOWrite16(addr, val);
|
2018-04-24 20:31:52 +00:00
|
|
|
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))
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.WriteSPICnt(val & 0xFFFF);
|
|
|
|
NDSCartSlot.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))
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.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))
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.SetROMCommand(0, val & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(1, (val >> 8) & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(2, (val >> 16) & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(3, val >> 24);
|
2021-04-24 22:48:02 +00:00
|
|
|
}
|
2017-03-30 23:50:01 +00:00
|
|
|
return;
|
|
|
|
case 0x040001AC:
|
2021-04-24 22:48:02 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11))
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
NDSCartSlot.SetROMCommand(4, val & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(5, (val >> 8) & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(6, (val >> 16) & 0xFF);
|
|
|
|
NDSCartSlot.SetROMCommand(7, val >> 24);
|
2021-04-24 22:48:02 +00:00
|
|
|
}
|
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:
|
2023-11-28 22:16:41 +00:00
|
|
|
SPI.WriteCnt(val & 0xFFFF);
|
|
|
|
SPI.WriteData((val >> 16) & 0xFF);
|
2020-10-25 17:14:40 +00:00
|
|
|
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;
|
2023-11-28 22:16:41 +00:00
|
|
|
SPU.SetPowerCnt(val & 0x0001);
|
|
|
|
Wifi.SetPowerCnt(val & 0x0002);
|
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 (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:
|
2023-11-28 22:16:41 +00:00
|
|
|
if (ExMemCnt[0] & (1<<11)) NDSCartSlot.WriteROMData(val);
|
2021-04-24 22:48:02 +00:00
|
|
|
return;
|
2017-01-17 01:29:25 +00:00
|
|
|
}
|
|
|
|
|
2017-01-20 00:18:30 +00:00
|
|
|
if (addr >= 0x04000400 && addr < 0x04000520)
|
|
|
|
{
|
2023-11-28 22:16:41 +00:00
|
|
|
SPU.Write32(addr, val);
|
2017-01-20 00:18:30 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-11-28 22:16:41 +00:00
|
|
|
Log(LogLevel::Debug, "unknown ARM7 IO write32 %08X %08X %08X\n", addr, val, ARM7.R[15]);
|
2016-05-16 15:48:40 +00:00
|
|
|
}
|
2023-11-25 17:32:09 +00:00
|
|
|
|
2023-12-08 17:29:30 +00:00
|
|
|
}
|