diff --git a/include/mgba/internal/ds/ds.h b/include/mgba/internal/ds/ds.h index f839592b1..be3289cd3 100644 --- a/include/mgba/internal/ds/ds.h +++ b/include/mgba/internal/ds/ds.h @@ -18,6 +18,7 @@ CXX_GUARD_START #include #include #include +#include extern const uint32_t DS_ARM946ES_FREQUENCY; extern const uint32_t DS_ARM7TDMI_FREQUENCY; @@ -85,6 +86,7 @@ struct DS { struct DSMemory memory; struct DSVideo video; struct DSGX gx; + struct DSWifi wifi; struct mCoreSync* sync; struct mTimingEvent slice; diff --git a/include/mgba/internal/ds/io.h b/include/mgba/internal/ds/io.h index 2ca1fda0b..50565ea2a 100644 --- a/include/mgba/internal/ds/io.h +++ b/include/mgba/internal/ds/io.h @@ -122,6 +122,9 @@ enum DS7IORegisters { DS7_REG_BIOSPROT_HI = 0x30A, DS7_REG_MAX = 0x51E, + + DS7_IO_BASE_WIFI = 0x800000, + DS7_IO_END_WIFI = 0x810000, }; enum DS9IORegisters { diff --git a/include/mgba/internal/ds/wifi.h b/include/mgba/internal/ds/wifi.h new file mode 100644 index 000000000..ed722e057 --- /dev/null +++ b/include/mgba/internal/ds/wifi.h @@ -0,0 +1,30 @@ +/* Copyright (c) 2013-2017 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef DS_WIFI_H +#define DS_WIFI_H + +#include + +CXX_GUARD_START + +#include + +mLOG_DECLARE_CATEGORY(DS_WIFI); + +struct DSWifi { + uint16_t io[0x800]; + uint16_t wram[0x1000]; + uint8_t baseband[0x100]; +}; + +struct DS; +void DSWifiReset(struct DS* ds); +void DSWifiWriteIO(struct DS* ds, uint32_t address, uint16_t value); +uint16_t DSWifiReadIO(struct DS* ds, uint32_t address); + +CXX_GUARD_END + +#endif diff --git a/src/ds/io.c b/src/ds/io.c index 3fbe37478..f4e555690 100644 --- a/src/ds/io.c +++ b/src/ds/io.c @@ -282,6 +282,10 @@ void DS7IOWrite(struct DS* ds, uint32_t address, uint16_t value) { return; } } + if (address >= DS7_IO_BASE_WIFI && address < DS7_IO_END_WIFI) { + DSWifiWriteIO(ds, address & 0x7FFF, value); + return; + } mLOG(DS_IO, STUB, "Stub DS7 I/O register write: %06X:%04X", address, value); if (address >= DS7_REG_MAX) { mLOG(DS_IO, GAME_ERROR, "Write to unused DS7 I/O register: %06X:%04X", address, value); @@ -391,11 +395,15 @@ uint16_t DS7IORead(struct DS* ds, uint32_t address) { return 0; } default: + if (address >= DS7_IO_BASE_WIFI && address < DS7_IO_END_WIFI) { + return DSWifiReadIO(ds, address & 0x7FFF); + } mLOG(DS_IO, STUB, "Stub DS7 I/O register read: %06X", address); } if (address < DS7_REG_MAX) { return ds->memory.io7[address >> 1]; } + return 0; } diff --git a/src/ds/wifi.c b/src/ds/wifi.c new file mode 100644 index 000000000..418c5a826 --- /dev/null +++ b/src/ds/wifi.c @@ -0,0 +1,88 @@ +/* Copyright (c) 2013-2017 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include + +#include +#include + +mLOG_DEFINE_CATEGORY(DS_WIFI, "DS Wi-Fi", "ds.wifi"); + +void DSWifiReset(struct DS* ds) { + memset(ds->wifi.io, 0, sizeof(ds->wifi.io)); + memset(ds->wifi.wram, 0, sizeof(ds->wifi.wram)); +} + +static void DSWifiWriteBB(struct DS* ds, uint8_t address, uint8_t value) { + mLOG(DS_WIFI, STUB, "Stub Wi-Fi baseband register write: %02X:%02X", address, value); + ds->wifi.baseband[address] = value; +} + +static uint8_t DSWifiReadBB(struct DS* ds, uint8_t address) { + mLOG(DS_WIFI, STUB, "Stub Wi-Fi baseband register read: %02X", address); + return ds->wifi.baseband[address]; +} + +static void DSWifiWriteReg(struct DS* ds, uint32_t address, uint16_t value) { + switch (address) { + case 0x158: + if (value & 0x1000) { + DSWifiWriteBB(ds, value & 0xFF, ds->wifi.io[0x15A >> 1]); + } + if (value & 0x2000) { + ds->wifi.io[0x15C >> 1] = DSWifiReadBB(ds, value & 0xFF); + } + break; + case 0x15A: + break; + default: + mLOG(DS_WIFI, STUB, "Stub Wi-Fi I/O register write: %06X:%04X", address, value); + break; + } + ds->wifi.io[address >> 1] = value; +} + +static uint16_t DSWifiReadReg(struct DS* ds, uint32_t address) { + switch (address) { + case 0x15C: + break; + default: + mLOG(DS_WIFI, STUB, "Stub Wi-Fi I/O register read: %06X", address); + break; + } + return ds->wifi.io[address >> 1]; +} + +void DSWifiWriteIO(struct DS* ds, uint32_t address, uint16_t value) { + switch (address >> 12) { + case 0: + case 1: + case 6: + case 7: + DSWifiWriteReg(ds, address & 0xFFF, value); + break; + case 4: + case 5: + STORE_16(value, address & 0x1FFE, ds->wifi.wram); + break; + } +} + +uint16_t DSWifiReadIO(struct DS* ds, uint32_t address) { + uint16_t value = 0; + switch (address >> 12) { + case 0: + case 1: + case 6: + case 7: + value = DSWifiReadReg(ds, address & 0xFFF); + break; + case 4: + case 5: + LOAD_16(value, address & 0x1FFE, ds->wifi.wram); + break; + } + return value; +}