src/ds/wifi.c (view raw)
1/* Copyright (c) 2013-2017 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include <mgba/internal/ds/wifi.h>
7
8#include <mgba/internal/arm/macros.h>
9#include <mgba/internal/ds/ds.h>
10
11mLOG_DEFINE_CATEGORY(DS_WIFI, "DS Wi-Fi", "ds.wifi");
12
13void DSWifiReset(struct DS* ds) {
14 memset(ds->wifi.io, 0, sizeof(ds->wifi.io));
15 ds->wifi.io[0x044 >> 1] = 1;
16 memset(ds->wifi.wram, 0, sizeof(ds->wifi.wram));
17}
18
19static void _rotateRandom(struct DS* ds) {
20 int16_t random = ds->wifi.io[0x044 >> 1];
21 ds->wifi.io[0x044 >> 1] = (random & 1) ^ ((random >> 10) | ((random << 1) & 0x7FE));
22}
23
24static void DSWifiWriteBB(struct DS* ds, uint8_t address, uint8_t value) {
25 mLOG(DS_WIFI, STUB, "Stub Wi-Fi baseband register write: %02X:%02X", address, value);
26 ds->wifi.baseband[address] = value;
27}
28
29static uint8_t DSWifiReadBB(struct DS* ds, uint8_t address) {
30 mLOG(DS_WIFI, STUB, "Stub Wi-Fi baseband register read: %02X", address);
31 return ds->wifi.baseband[address];
32}
33
34static void DSWifiWriteReg(struct DS* ds, uint32_t address, uint16_t value) {
35 switch (address) {
36 case 0x040:
37 value &= 0x8001;
38 if (value & 0x8000) {
39 uint16_t state = ds->wifi.io[0x03C >> 1];
40 if (value & 0x1) {
41 state |= 0x200;
42 state &= ~0x100;
43 } else {
44 mLOG(DS_WIFI, STUB, "Stub Wi-Fi I/O register write: %06X:%04X", address, value);
45 state &= ~0x200;
46 }
47 ds->wifi.io[0x03C >> 1] = state;
48 }
49 break;
50 case 0x158:
51 if (value & 0x1000) {
52 DSWifiWriteBB(ds, value & 0xFF, ds->wifi.io[0x15A >> 1]);
53 }
54 if (value & 0x2000) {
55 ds->wifi.io[0x15C >> 1] = DSWifiReadBB(ds, value & 0xFF);
56 }
57 break;
58 case 0x15A:
59 break;
60 default:
61 mLOG(DS_WIFI, STUB, "Stub Wi-Fi I/O register write: %06X:%04X", address, value);
62 break;
63 }
64 ds->wifi.io[address >> 1] = value;
65}
66
67static uint16_t DSWifiReadReg(struct DS* ds, uint32_t address) {
68 switch (address) {
69 case 0x044:
70 _rotateRandom(ds);
71 break;
72 case 0x040:
73 case 0x15C:
74 break;
75 case 0x254:
76 return 0xFFFF;
77 case 0x290:
78 return 0xFFFF;
79 default:
80 mLOG(DS_WIFI, STUB, "Stub Wi-Fi I/O register read: %06X", address);
81 break;
82 }
83 return ds->wifi.io[address >> 1];
84}
85
86void DSWifiWriteIO(struct DS* ds, uint32_t address, uint16_t value) {
87 switch (address >> 12) {
88 case 0:
89 case 1:
90 case 6:
91 case 7:
92 DSWifiWriteReg(ds, address & 0xFFF, value);
93 break;
94 case 4:
95 case 5:
96 STORE_16(value, address & 0x1FFE, ds->wifi.wram);
97 break;
98 }
99}
100
101uint16_t DSWifiReadIO(struct DS* ds, uint32_t address) {
102 uint16_t value = 0;
103 switch (address >> 12) {
104 case 0:
105 case 1:
106 case 6:
107 case 7:
108 value = DSWifiReadReg(ds, address & 0xFFF);
109 break;
110 case 4:
111 case 5:
112 LOAD_16(value, address & 0x1FFE, ds->wifi.wram);
113 break;
114 }
115 return value;
116}