-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmemory.cpp
2885 lines (2784 loc) · 174 KB
/
memory.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
Copyright 2019-2020 Hydr8gon
This file is part of NooDS.
NooDS 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.
NooDS 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 NooDS. If not, see <https://www.gnu.org/licenses/>.
*/
#include <cstring>
#include "memory.h"
#include "core.h"
#include "settings.h"
void Memory::loadBios()
{
// Attempt to load the ARM9 BIOS
FILE *bios9File = fopen(Settings::getBios9Path().c_str(), "rb");
if (!bios9File) return;
fread(bios9, sizeof(uint8_t), 0x1000, bios9File);
fclose(bios9File);
// Attempt to load the ARM7 BIOS
FILE *bios7File = fopen(Settings::getBios7Path().c_str(), "rb");
if (!bios7File) return;
fread(bios7, sizeof(uint8_t), 0x4000, bios7File);
fclose(bios7File);
}
void Memory::loadGbaBios()
{
// Attempt to load the GBA BIOS
FILE *gbaBiosFile = fopen(Settings::getGbaBiosPath().c_str(), "rb");
if (!gbaBiosFile) return;
fread(gbaBios, sizeof(uint8_t), 0x4000, gbaBiosFile);
fclose(gbaBiosFile);
}
template int8_t Memory::read(bool cpu, uint32_t address);
template int16_t Memory::read(bool cpu, uint32_t address);
template uint8_t Memory::read(bool cpu, uint32_t address);
template uint16_t Memory::read(bool cpu, uint32_t address);
template uint32_t Memory::read(bool cpu, uint32_t address);
template <typename T> T Memory::read(bool cpu, uint32_t address)
{
// Align the address
address &= ~(sizeof(T) - 1);
uint8_t *data = nullptr;
if (cpu == 0) // ARM9
{
// Get a pointer to the ARM9 memory mapped to the given address
if (core->cp15.getItcmEnabled() && address < core->cp15.getItcmSize()) // Instruction TCM
{
data = &instrTcm[address & 0x7FFF];
}
else if (core->cp15.getDtcmEnabled() && address >= core->cp15.getDtcmAddr() &&
address < core->cp15.getDtcmAddr() + core->cp15.getDtcmSize()) // Data TCM
{
data = &dataTcm[(address - core->cp15.getDtcmAddr()) & 0x3FFF];
}
else
{
switch (address & 0xFF000000)
{
case 0x02000000: // Main RAM
{
data = &ram[address & 0x3FFFFF];
break;
}
case 0x03000000: // Shared WRAM
{
switch (wramCnt)
{
case 0: data = &wram[(address & 0x7FFF)]; break;
case 1: data = &wram[(address & 0x3FFF) + 0x4000]; break;
case 2: data = &wram[(address & 0x3FFF)]; break;
}
break;
}
case 0x04000000: // I/O registers
{
return ioRead9<T>(address);
}
case 0x05000000: // Palettes
{
data = &palette[address & 0x7FF];
break;
}
case 0x06000000: // VRAM
{
switch (address & 0xFFE00000)
{
case 0x06000000: data = engABg[(address & 0x7FFFF) >> 14]; break;
case 0x06200000: data = engBBg[(address & 0x1FFFF) >> 14]; break;
case 0x06400000: data = engAObj[(address & 0x3FFFF) >> 14]; break;
case 0x06600000: data = engBObj[(address & 0x1FFFF) >> 14]; break;
default: data = lcdc[(address & 0xFFFFF) >> 14]; break;
}
if (data) data += (address & 0x3FFF);
break;
}
case 0x07000000: // OAM
{
data = &oam[address & 0x7FF];
break;
}
case 0x08000000: case 0x09000000: // GBA ROM
{
if ((address & 0x01FFFFFF) < core->cartridge.getGbaRomSize())
{
data = &core->cartridge.getGbaRom()[address & 0x01FFFFFF];
break;
}
return (T)0xFFFFFFFF;
}
case 0x0A000000: // GBA SRAM
{
return core->cartridge.gbaSramRead(address + 0x4000000);
}
case 0xFF000000: // ARM9 BIOS
{
if ((address & 0xFFFF8000) == 0xFFFF0000)
data = &bios9[address & 0xFFFF];
break;
}
}
}
}
else // ARM7
{
// Get a pointer to the ARM7 memory mapped to the given address
switch (address & 0xFF000000)
{
case 0x00000000: // ARM7 BIOS
{
if (address < 0x4000)
data = &bios7[address];
break;
}
case 0x02000000: // Main RAM
{
data = &ram[address & 0x3FFFFF];
break;
}
case 0x03000000: // WRAM
{
if (!(address & 0x00800000)) // Shared WRAM
{
switch (wramCnt)
{
case 1: data = &wram[(address & 0x3FFF)]; break;
case 2: data = &wram[(address & 0x3FFF) + 0x4000]; break;
case 3: data = &wram[(address & 0x7FFF)]; break;
}
}
if (!data) data = &wram7[address & 0xFFFF]; // ARM7 WRAM
break;
}
case 0x04000000: // I/O registers
{
if (address & 0x00800000) // WiFi regions
{
address &= ~0x00008000; // Mirror the regions
if (address >= 0x04804000 && address < 0x04806000) // WiFi RAM
data = &wifiRam[address & 0x1FFF];
else if (address < 0x04808000) // WiFi I/O registers
return ioRead7<T>(address);
break;
}
else
{
return ioRead7<T>(address);
}
}
case 0x06000000: // VRAM
{
data = vram7[(address & 0x3FFFF) >> 17];
if (data) data += (address & 0x1FFFF);
break;
}
case 0x08000000: case 0x09000000: // GBA ROM
{
if ((address & 0x01FFFFFF) < core->cartridge.getGbaRomSize())
{
data = &core->cartridge.getGbaRom()[address & 0x01FFFFFF];
break;
}
return (T)0xFFFFFFFF;
}
case 0x0A000000: // GBA SRAM
{
return core->cartridge.gbaSramRead(address + 0x4000000);
}
}
}
T value = 0;
if (data)
{
// Form an LSB-first value from the data at the pointer
for (unsigned int i = 0; i < sizeof(T); i++)
value |= data[i] << (i * 8);
}
else if (core->isGbaMode())
{
printf("Unmapped GBA memory read: 0x%X\n", address);
}
else
{
printf("Unmapped ARM%d memory read: 0x%X\n", ((cpu == 0) ? 9 : 7), address);
}
return value;
}
template void Memory::write(bool cpu, uint32_t address, uint8_t value);
template void Memory::write(bool cpu, uint32_t address, uint16_t value);
template void Memory::write(bool cpu, uint32_t address, uint32_t value);
template <typename T> void Memory::write(bool cpu, uint32_t address, T value)
{
// Align the address
address &= ~(sizeof(T) - 1);
uint8_t *data = nullptr;
if (cpu == 0) // ARM9
{
// Get a pointer to the ARM9 memory mapped to the given address
if (core->cp15.getItcmEnabled() && address < core->cp15.getItcmSize()) // Instruction TCM
{
data = &instrTcm[address & 0x7FFF];
}
else if (core->cp15.getDtcmEnabled() && address >= core->cp15.getDtcmAddr() &&
address < core->cp15.getDtcmAddr() + core->cp15.getDtcmSize()) // Data TCM
{
data = &dataTcm[(address - core->cp15.getDtcmAddr()) & 0x3FFF];
}
else
{
switch (address & 0xFF000000)
{
case 0x02000000: // Main RAM
{
data = &ram[address & 0x3FFFFF];
break;
}
case 0x03000000: // Shared WRAM
{
switch (wramCnt)
{
case 0: data = &wram[(address & 0x7FFF)]; break;
case 1: data = &wram[(address & 0x3FFF) + 0x4000]; break;
case 2: data = &wram[(address & 0x3FFF)]; break;
}
break;
}
case 0x04000000: // I/O registers
{
ioWrite9<T>(address, value);
return;
}
case 0x05000000: // Palettes
{
data = &palette[address & 0x7FF];
break;
}
case 0x06000000: // VRAM
{
switch (address & 0xFFE00000)
{
case 0x06000000: data = engABg[(address & 0x7FFFF) >> 14]; break;
case 0x06200000: data = engBBg[(address & 0x1FFFF) >> 14]; break;
case 0x06400000: data = engAObj[(address & 0x3FFFF) >> 14]; break;
case 0x06600000: data = engBObj[(address & 0x1FFFF) >> 14]; break;
default: data = lcdc[(address & 0xFFFFF) >> 14]; break;
}
if (data) data += (address & 0x3FFF);
break;
}
case 0x07000000: // OAM
{
data = &oam[address & 0x7FF];
break;
}
case 0x0A000000: // GBA SRAM
{
core->cartridge.gbaSramWrite(address + 0x4000000, value);
return;
}
}
}
}
else // ARM7
{
// Get a pointer to the ARM7 memory mapped to the given address
switch (address & 0xFF000000)
{
case 0x02000000: // Main RAM
{
data = &ram[address & 0x3FFFFF];
break;
}
case 0x03000000: // WRAM
{
if (!(address & 0x00800000)) // Shared WRAM
{
switch (wramCnt)
{
case 1: data = &wram[(address & 0x3FFF)]; break;
case 2: data = &wram[(address & 0x3FFF) + 0x4000]; break;
case 3: data = &wram[(address & 0x7FFF)]; break;
}
}
if (!data) data = &wram7[address & 0xFFFF]; // ARM7 WRAM
break;
}
case 0x04000000: // I/O registers
{
if (address & 0x00800000) // WiFi regions
{
return; //Disable Wifi on PSP
if (sizeof(T) == 1) return; // Ignore single-byte writes
address &= ~0x00008000; // Mirror the regions
if (address >= 0x04804000 && address < 0x04806000) // WiFi RAM
{
data = &wifiRam[address & 0x1FFF];
}
else if (address < 0x04808000) // WiFi I/O registers
{
ioWrite7<T>(address, value);
return;
}
break;
}
else
{
ioWrite7<T>(address, value);
return;
}
}
case 0x06000000: // VRAM
{
data = vram7[(address & 0x3FFFF) >> 17];
if (data) data += (address & 0x1FFFF);
break;
}
case 0x0A000000: // GBA SRAM
{
core->cartridge.gbaSramWrite(address + 0x4000000, value);
return;
}
}
}
if (data)
{
// Write an LSB-first value to the data at the pointer
for (unsigned int i = 0; i < sizeof(T); i++)
data[i] = value >> (i * 8);
}
}
template <typename T> T Memory::ioRead9(uint32_t address)
{
T value = 0;
unsigned int i = 0;
// Read a value from one or more ARM9 I/O registers
while (i < sizeof(T))
{
uint32_t base = address + i;
unsigned int size;
uint32_t data;
switch (base)
{
case 0x4000000:
case 0x4000001:
case 0x4000002:
case 0x4000003: base -= 0x4000000; size = 4; data = core->gpu2D[0].readDispCnt(); break; // DISPCNT (engine A)
case 0x4000004:
case 0x4000005: base -= 0x4000004; size = 2; data = core->gpu.readDispStat(0); break; // DISPSTAT (ARM9)
case 0x4000006:
case 0x4000007: base -= 0x4000006; size = 2; data = core->gpu.readVCount(); break; // VCOUNT
case 0x4000008:
case 0x4000009: base -= 0x4000008; size = 2; data = core->gpu2D[0].readBgCnt(0); break; // BG0CNT (engine A)
case 0x400000A:
case 0x400000B: base -= 0x400000A; size = 2; data = core->gpu2D[0].readBgCnt(1); break; // BG1CNT (engine A)
case 0x400000C:
case 0x400000D: base -= 0x400000C; size = 2; data = core->gpu2D[0].readBgCnt(2); break; // BG2CNT (engine A)
case 0x400000E:
case 0x400000F: base -= 0x400000E; size = 2; data = core->gpu2D[0].readBgCnt(3); break; // BG3CNT (engine A)
case 0x4000048:
case 0x4000049: base -= 0x4000048; size = 2; data = core->gpu2D[0].readWinIn(); break; // WININ (engine A)
case 0x400004A:
case 0x400004B: base -= 0x400004A; size = 2; data = core->gpu2D[0].readWinOut(); break; // WINOUT (engine A)
case 0x4000050:
case 0x4000051: base -= 0x4000050; size = 2; data = core->gpu2D[0].readBldCnt(); break; // BLDCNT (engine A)
case 0x4000052:
case 0x4000053: base -= 0x4000052; size = 2; data = core->gpu2D[0].readBldAlpha(); break; // BLDALPHA (engine A)
case 0x4000060:
case 0x4000061: base -= 0x4000060; size = 2; data = core->gpu3DRenderer.readDisp3DCnt(); break; // DISP3DCNT
case 0x4000064:
case 0x4000065:
case 0x4000066:
case 0x4000067: base -= 0x4000064; size = 4; data = core->gpu.readDispCapCnt(); break; // DISPCAPCNT
case 0x400006C:
case 0x400006D: base -= 0x400006C; size = 2; data = core->gpu2D[0].readMasterBright(); break; // MASTER_BRIGHT (engine A)
case 0x40000B0:
case 0x40000B1:
case 0x40000B2:
case 0x40000B3: base -= 0x40000B0; size = 4; data = core->dma[0].readDmaSad(0); break; // DMA0SAD (ARM9)
case 0x40000B4:
case 0x40000B5:
case 0x40000B6:
case 0x40000B7: base -= 0x40000B4; size = 4; data = core->dma[0].readDmaDad(0); break; // DMA0DAD (ARM9)
case 0x40000B8:
case 0x40000B9:
case 0x40000BA:
case 0x40000BB: base -= 0x40000B8; size = 4; data = core->dma[0].readDmaCnt(0); break; // DMA0CNT (ARM9)
case 0x40000BC:
case 0x40000BD:
case 0x40000BE:
case 0x40000BF: base -= 0x40000BC; size = 4; data = core->dma[0].readDmaSad(1); break; // DMA1SAD (ARM9)
case 0x40000C0:
case 0x40000C1:
case 0x40000C2:
case 0x40000C3: base -= 0x40000C0; size = 4; data = core->dma[0].readDmaDad(1); break; // DMA1DAD (ARM9)
case 0x40000C4:
case 0x40000C5:
case 0x40000C6:
case 0x40000C7: base -= 0x40000C4; size = 4; data = core->dma[0].readDmaCnt(1); break; // DMA1CNT (ARM9)
case 0x40000C8:
case 0x40000C9:
case 0x40000CA:
case 0x40000CB: base -= 0x40000C8; size = 4; data = core->dma[0].readDmaSad(2); break; // DMA2SAD (ARM9)
case 0x40000CC:
case 0x40000CD:
case 0x40000CE:
case 0x40000CF: base -= 0x40000CC; size = 4; data = core->dma[0].readDmaDad(2); break; // DMA2DAD (ARM9)
case 0x40000D0:
case 0x40000D1:
case 0x40000D2:
case 0x40000D3: base -= 0x40000D0; size = 4; data = core->dma[0].readDmaCnt(2); break; // DMA2CNT (ARM9)
case 0x40000D4:
case 0x40000D5:
case 0x40000D6:
case 0x40000D7: base -= 0x40000D4; size = 4; data = core->dma[0].readDmaSad(3); break; // DMA3SAD (ARM9)
case 0x40000D8:
case 0x40000D9:
case 0x40000DA:
case 0x40000DB: base -= 0x40000D8; size = 4; data = core->dma[0].readDmaDad(3); break; // DMA3DAD (ARM9)
case 0x40000DC:
case 0x40000DD:
case 0x40000DE:
case 0x40000DF: base -= 0x40000DC; size = 4; data = core->dma[0].readDmaCnt(3); break; // DMA3CNT (ARM9)
case 0x40000E0:
case 0x40000E1:
case 0x40000E2:
case 0x40000E3: base -= 0x40000E0; size = 4; data = readDmaFill(0); break; // DMA0FILL
case 0x40000E4:
case 0x40000E5:
case 0x40000E6:
case 0x40000E7: base -= 0x40000E4; size = 4; data = readDmaFill(1); break; // DMA1FILL
case 0x40000E8:
case 0x40000E9:
case 0x40000EA:
case 0x40000EB: base -= 0x40000E8; size = 4; data = readDmaFill(2); break; // DMA2FILL
case 0x40000EC:
case 0x40000ED:
case 0x40000EE:
case 0x40000EF: base -= 0x40000EC; size = 4; data = readDmaFill(3); break; // DMA3FILL
case 0x4000100:
case 0x4000101: base -= 0x4000100; size = 2; data = core->timers[0].readTmCntL(0); break; // TM0CNT_L (ARM9)
case 0x4000102:
case 0x4000103: base -= 0x4000102; size = 2; data = core->timers[0].readTmCntH(0); break; // TM0CNT_H (ARM9)
case 0x4000104:
case 0x4000105: base -= 0x4000104; size = 2; data = core->timers[0].readTmCntL(1); break; // TM1CNT_L (ARM9)
case 0x4000106:
case 0x4000107: base -= 0x4000106; size = 2; data = core->timers[0].readTmCntH(1); break; // TM1CNT_H (ARM9)
case 0x4000108:
case 0x4000109: base -= 0x4000108; size = 2; data = core->timers[0].readTmCntL(2); break; // TM2CNT_L (ARM9)
case 0x400010A:
case 0x400010B: base -= 0x400010A; size = 2; data = core->timers[0].readTmCntH(2); break; // TM2CNT_H (ARM9)
case 0x400010C:
case 0x400010D: base -= 0x400010C; size = 2; data = core->timers[0].readTmCntL(3); break; // TM3CNT_L (ARM9)
case 0x400010E:
case 0x400010F: base -= 0x400010E; size = 2; data = core->timers[0].readTmCntH(3); break; // TM3CNT_H (ARM9)
case 0x4000130:
case 0x4000131: base -= 0x4000130; size = 2; data = core->input.readKeyInput(); break; // KEYINPUT
case 0x4000180:
case 0x4000181: base -= 0x4000180; size = 2; data = core->ipc.readIpcSync(0); break; // IPCSYNC (ARM9)
case 0x4000184:
case 0x4000185: base -= 0x4000184; size = 2; data = core->ipc.readIpcFifoCnt(0); break; // IPCFIFOCNT (ARM9)
case 0x40001A0:
case 0x40001A1: base -= 0x40001A0; size = 2; data = core->cartridge.readAuxSpiCnt(0); break; // AUXSPICNT (ARM9)
case 0x40001A2: base -= 0x40001A2; size = 1; data = core->cartridge.readAuxSpiData(0); break; // AUXSPIDATA (ARM9)
case 0x40001A4:
case 0x40001A5:
case 0x40001A6:
case 0x40001A7: base -= 0x40001A4; size = 4; data = core->cartridge.readRomCtrl(0); break; // ROMCTRL (ARM9)
case 0x4000208: base -= 0x4000208; size = 1; data = core->interpreter[0].readIme(); break; // IME (ARM9)
case 0x4000210:
case 0x4000211:
case 0x4000212:
case 0x4000213: base -= 0x4000210; size = 4; data = core->interpreter[0].readIe(); break; // IE (ARM9)
case 0x4000214:
case 0x4000215:
case 0x4000216:
case 0x4000217: base -= 0x4000214; size = 4; data = core->interpreter[0].readIrf(); break; // IF (ARM9)
case 0x4000240: base -= 0x4000240; size = 1; data = readVramCnt(0); break; // VRAMCNT_A
case 0x4000241: base -= 0x4000241; size = 1; data = readVramCnt(1); break; // VRAMCNT_B
case 0x4000242: base -= 0x4000242; size = 1; data = readVramCnt(2); break; // VRAMCNT_C
case 0x4000243: base -= 0x4000243; size = 1; data = readVramCnt(3); break; // VRAMCNT_D
case 0x4000244: base -= 0x4000244; size = 1; data = readVramCnt(4); break; // VRAMCNT_E
case 0x4000245: base -= 0x4000245; size = 1; data = readVramCnt(5); break; // VRAMCNT_F
case 0x4000246: base -= 0x4000246; size = 1; data = readVramCnt(6); break; // VRAMCNT_G
case 0x4000247: base -= 0x4000247; size = 1; data = readWramCnt(); break; // WRAMCNT
case 0x4000248: base -= 0x4000248; size = 1; data = readVramCnt(7); break; // VRAMCNT_H
case 0x4000249: base -= 0x4000249; size = 1; data = readVramCnt(8); break; // VRAMCNT_I
case 0x4000280:
case 0x4000281: base -= 0x4000280; size = 2; data = core->divSqrt.readDivCnt(); break; // DIVCNT
case 0x4000290:
case 0x4000291:
case 0x4000292:
case 0x4000293: base -= 0x4000290; size = 4; data = core->divSqrt.readDivNumerL(); break; // DIVNUMER_L
case 0x4000294:
case 0x4000295:
case 0x4000296:
case 0x4000297: base -= 0x4000294; size = 4; data = core->divSqrt.readDivNumerH(); break; // DIVNUMER_H
case 0x4000298:
case 0x4000299:
case 0x400029A:
case 0x400029B: base -= 0x4000298; size = 4; data = core->divSqrt.readDivDenomL(); break; // DIVDENOM_L
case 0x400029C:
case 0x400029D:
case 0x400029E:
case 0x400029F: base -= 0x400029C; size = 4; data = core->divSqrt.readDivDenomH(); break; // DIVDENOM_H
case 0x40002A0:
case 0x40002A1:
case 0x40002A2:
case 0x40002A3: base -= 0x40002A0; size = 4; data = core->divSqrt.readDivResultL(); break; // DIVRESULT_L
case 0x40002A4:
case 0x40002A5:
case 0x40002A6:
case 0x40002A7: base -= 0x40002A4; size = 4; data = core->divSqrt.readDivResultH(); break; // DIVRESULT_H
case 0x40002A8:
case 0x40002A9:
case 0x40002AA:
case 0x40002AB: base -= 0x40002A8; size = 4; data = core->divSqrt.readDivRemResultL(); break; // DIVREMRESULT_L
case 0x40002AC:
case 0x40002AD:
case 0x40002AE:
case 0x40002AF: base -= 0x40002AC; size = 4; data = core->divSqrt.readDivRemResultH(); break; // DIVREMRESULT_H
case 0x40002B0:
case 0x40002B1: base -= 0x40002B0; size = 2; data = core->divSqrt.readSqrtCnt(); break; // SQRTCNT
case 0x40002B4:
case 0x40002B5:
case 0x40002B6:
case 0x40002B7: base -= 0x40002B4; size = 4; data = core->divSqrt.readSqrtResult(); break; // SQRTRESULT
case 0x40002B8:
case 0x40002B9:
case 0x40002BA:
case 0x40002BB: base -= 0x40002B8; size = 4; data = core->divSqrt.readSqrtParamL(); break; // SQRTPARAM_L
case 0x40002BC:
case 0x40002BD:
case 0x40002BE:
case 0x40002BF: base -= 0x40002BC; size = 4; data = core->divSqrt.readSqrtParamH(); break; // SQRTPARAM_H
case 0x4000300: base -= 0x4000300; size = 1; data = core->interpreter[0].readPostFlg(); break; // POSTFLG (ARM9)
case 0x4000304:
case 0x4000305: base -= 0x4000304; size = 2; data = core->gpu.readPowCnt1(); break; // POWCNT1
case 0x4000600:
case 0x4000601:
case 0x4000602:
case 0x4000603: base -= 0x4000600; size = 4; data = core->gpu3D.readGxStat(); break; // GXSTAT
case 0x4000604:
case 0x4000605:
case 0x4000606:
case 0x4000607: base -= 0x4000604; size = 4; data = core->gpu3D.readRamCount(); break; // RAM_COUNT
case 0x4000620:
case 0x4000621:
case 0x4000622:
case 0x4000623: base -= 0x4000620; size = 4; data = core->gpu3D.readPosResult(0); break; // POS_RESULT
case 0x4000624:
case 0x4000625:
case 0x4000626:
case 0x4000627: base -= 0x4000624; size = 4; data = core->gpu3D.readPosResult(1); break; // POS_RESULT
case 0x4000628:
case 0x4000629:
case 0x400062A:
case 0x400062B: base -= 0x4000628; size = 4; data = core->gpu3D.readPosResult(2); break; // POS_RESULT
case 0x400062C:
case 0x400062D:
case 0x400062E:
case 0x400062F: base -= 0x400062C; size = 4; data = core->gpu3D.readPosResult(3); break; // POS_RESULT
case 0x4000630:
case 0x4000631: base -= 0x4000630; size = 2; data = core->gpu3D.readVecResult(0); break; // VEC_RESULT
case 0x4000632:
case 0x4000633: base -= 0x4000632; size = 2; data = core->gpu3D.readVecResult(1); break; // VEC_RESULT
case 0x4000634:
case 0x4000635: base -= 0x4000634; size = 2; data = core->gpu3D.readVecResult(2); break; // VEC_RESULT
case 0x4000640:
case 0x4000641:
case 0x4000642:
case 0x4000643: base -= 0x4000640; size = 4; data = core->gpu3D.readClipMtxResult(0); break; // CLIPMTX_RESULT
case 0x4000644:
case 0x4000645:
case 0x4000646:
case 0x4000647: base -= 0x4000644; size = 4; data = core->gpu3D.readClipMtxResult(1); break; // CLIPMTX_RESULT
case 0x4000648:
case 0x4000649:
case 0x400064A:
case 0x400064B: base -= 0x4000648; size = 4; data = core->gpu3D.readClipMtxResult(2); break; // CLIPMTX_RESULT
case 0x400064C:
case 0x400064D:
case 0x400064E:
case 0x400064F: base -= 0x400064C; size = 4; data = core->gpu3D.readClipMtxResult(3); break; // CLIPMTX_RESULT
case 0x4000650:
case 0x4000651:
case 0x4000652:
case 0x4000653: base -= 0x4000650; size = 4; data = core->gpu3D.readClipMtxResult(4); break; // CLIPMTX_RESULT
case 0x4000654:
case 0x4000655:
case 0x4000656:
case 0x4000657: base -= 0x4000654; size = 4; data = core->gpu3D.readClipMtxResult(5); break; // CLIPMTX_RESULT
case 0x4000658:
case 0x4000659:
case 0x400065A:
case 0x400065B: base -= 0x4000658; size = 4; data = core->gpu3D.readClipMtxResult(6); break; // CLIPMTX_RESULT
case 0x400065C:
case 0x400065D:
case 0x400065E:
case 0x400065F: base -= 0x400065C; size = 4; data = core->gpu3D.readClipMtxResult(7); break; // CLIPMTX_RESULT
case 0x4000660:
case 0x4000661:
case 0x4000662:
case 0x4000663: base -= 0x4000660; size = 4; data = core->gpu3D.readClipMtxResult(8); break; // CLIPMTX_RESULT
case 0x4000664:
case 0x4000665:
case 0x4000666:
case 0x4000667: base -= 0x4000664; size = 4; data = core->gpu3D.readClipMtxResult(9); break; // CLIPMTX_RESULT
case 0x4000668:
case 0x4000669:
case 0x400066A:
case 0x400066B: base -= 0x4000668; size = 4; data = core->gpu3D.readClipMtxResult(10); break; // CLIPMTX_RESULT
case 0x400066C:
case 0x400066D:
case 0x400066E:
case 0x400066F: base -= 0x400066C; size = 4; data = core->gpu3D.readClipMtxResult(11); break; // CLIPMTX_RESULT
case 0x4000670:
case 0x4000671:
case 0x4000672:
case 0x4000673: base -= 0x4000670; size = 4; data = core->gpu3D.readClipMtxResult(12); break; // CLIPMTX_RESULT
case 0x4000674:
case 0x4000675:
case 0x4000676:
case 0x4000677: base -= 0x4000674; size = 4; data = core->gpu3D.readClipMtxResult(13); break; // CLIPMTX_RESULT
case 0x4000678:
case 0x4000679:
case 0x400067A:
case 0x400067B: base -= 0x4000678; size = 4; data = core->gpu3D.readClipMtxResult(14); break; // CLIPMTX_RESULT
case 0x400067C:
case 0x400067D:
case 0x400067E:
case 0x400067F: base -= 0x400067C; size = 4; data = core->gpu3D.readClipMtxResult(15); break; // CLIPMTX_RESULT
case 0x4000680:
case 0x4000681:
case 0x4000682:
case 0x4000683: base -= 0x4000680; size = 4; data = core->gpu3D.readVecMtxResult(0); break; // VECMTX_RESULT
case 0x4000684:
case 0x4000685:
case 0x4000686:
case 0x4000687: base -= 0x4000684; size = 4; data = core->gpu3D.readVecMtxResult(1); break; // VECMTX_RESULT
case 0x4000688:
case 0x4000689:
case 0x400068A:
case 0x400068B: base -= 0x4000688; size = 4; data = core->gpu3D.readVecMtxResult(2); break; // VECMTX_RESULT
case 0x400068C:
case 0x400068D:
case 0x400068E:
case 0x400068F: base -= 0x400068C; size = 4; data = core->gpu3D.readVecMtxResult(3); break; // VECMTX_RESULT
case 0x4000690:
case 0x4000691:
case 0x4000692:
case 0x4000693: base -= 0x4000690; size = 4; data = core->gpu3D.readVecMtxResult(4); break; // VECMTX_RESULT
case 0x4000694:
case 0x4000695:
case 0x4000696:
case 0x4000697: base -= 0x4000694; size = 4; data = core->gpu3D.readVecMtxResult(5); break; // VECMTX_RESULT
case 0x4000698:
case 0x4000699:
case 0x400069A:
case 0x400069B: base -= 0x4000698; size = 4; data = core->gpu3D.readVecMtxResult(6); break; // VECMTX_RESULT
case 0x400069C:
case 0x400069D:
case 0x400069E:
case 0x400069F: base -= 0x400069C; size = 4; data = core->gpu3D.readVecMtxResult(7); break; // VECMTX_RESULT
case 0x40006A0:
case 0x40006A1:
case 0x40006A2:
case 0x40006A3: base -= 0x40006A0; size = 4; data = core->gpu3D.readVecMtxResult(8); break; // VECMTX_RESULT
case 0x4001000:
case 0x4001001:
case 0x4001002:
case 0x4001003: base -= 0x4001000; size = 4; data = core->gpu2D[1].readDispCnt(); break; // DISPCNT (engine B)
case 0x4001008:
case 0x4001009: base -= 0x4001008; size = 2; data = core->gpu2D[1].readBgCnt(0); break; // BG0CNT (engine B)
case 0x400100A:
case 0x400100B: base -= 0x400100A; size = 2; data = core->gpu2D[1].readBgCnt(1); break; // BG1CNT (engine B)
case 0x400100C:
case 0x400100D: base -= 0x400100C; size = 2; data = core->gpu2D[1].readBgCnt(2); break; // BG2CNT (engine B)
case 0x400100E:
case 0x400100F: base -= 0x400100E; size = 2; data = core->gpu2D[1].readBgCnt(3); break; // BG3CNT (engine B)
case 0x4001048:
case 0x4001049: base -= 0x4001048; size = 2; data = core->gpu2D[1].readWinIn(); break; // WININ (engine B)
case 0x400104A:
case 0x400104B: base -= 0x400104A; size = 2; data = core->gpu2D[1].readWinOut(); break; // WINOUT (engine B)
case 0x4001050:
case 0x4001051: base -= 0x4001050; size = 2; data = core->gpu2D[1].readBldCnt(); break; // BLDCNT (engine B)
case 0x4001052:
case 0x4001053: base -= 0x4001052; size = 2; data = core->gpu2D[1].readBldAlpha(); break; // BLDALPHA (engine B)
case 0x400106C:
case 0x400106D: base -= 0x400106C; size = 2; data = core->gpu2D[1].readMasterBright(); break; // MASTER_BRIGHT (engine B)
case 0x4100000:
case 0x4100001:
case 0x4100002:
case 0x4100003: base -= 0x4100000; size = 4; data = core->ipc.readIpcFifoRecv(0); break; // IPCFIFORECV (ARM9)
case 0x4100010:
case 0x4100011:
case 0x4100012:
case 0x4100013: base -= 0x4100010; size = 4; data = core->cartridge.readRomDataIn(0); break; // ROMDATAIN (ARM9)
default:
{
// Handle unknown reads by returning 0
if (i == 0)
{
printf("Unknown ARM9 I/O register read: 0x%X\n", address);
return 0;
}
// Ignore unknown reads if they occur after the first byte
// This is in case, for example, a 16-bit register is accessed with a 32-bit read
i++;
continue;
}
}
value |= (data >> (base * 8)) << (i * 8);
i += size - base;
}
return value;
}
template <typename T> T Memory::ioRead7(uint32_t address)
{
T value = 0;
unsigned int i = 0;
// Read a value from one or more ARM7 I/O registers
while (i < sizeof(T))
{
uint32_t base = address + i;
unsigned int size;
uint32_t data;
switch (base)
{
case 0x4000004:
case 0x4000005: base -= 0x4000004; size = 2; data = core->gpu.readDispStat(1); break; // DISPSTAT (ARM7)
case 0x4000006:
case 0x4000007: base -= 0x4000006; size = 2; data = core->gpu.readVCount(); break; // VCOUNT
case 0x40000B0:
case 0x40000B1:
case 0x40000B2:
case 0x40000B3: base -= 0x40000B0; size = 4; data = core->dma[1].readDmaSad(0); break; // DMA0SAD (ARM7)
case 0x40000B4:
case 0x40000B5:
case 0x40000B6:
case 0x40000B7: base -= 0x40000B4; size = 4; data = core->dma[1].readDmaDad(0); break; // DMA0DAD (ARM7)
case 0x40000B8:
case 0x40000B9:
case 0x40000BA:
case 0x40000BB: base -= 0x40000B8; size = 4; data = core->dma[1].readDmaCnt(0); break; // DMA0CNT (ARM7)
case 0x40000BC:
case 0x40000BD:
case 0x40000BE:
case 0x40000BF: base -= 0x40000BC; size = 4; data = core->dma[1].readDmaSad(1); break; // DMA1SAD (ARM7)
case 0x40000C0:
case 0x40000C1:
case 0x40000C2:
case 0x40000C3: base -= 0x40000C0; size = 4; data = core->dma[1].readDmaDad(1); break; // DMA1DAD (ARM7)
case 0x40000C4:
case 0x40000C5:
case 0x40000C6:
case 0x40000C7: base -= 0x40000C4; size = 4; data = core->dma[1].readDmaCnt(1); break; // DMA1CNT (ARM7)
case 0x40000C8:
case 0x40000C9:
case 0x40000CA:
case 0x40000CB: base -= 0x40000C8; size = 4; data = core->dma[1].readDmaSad(2); break; // DMA2SAD (ARM7)
case 0x40000CC:
case 0x40000CD:
case 0x40000CE:
case 0x40000CF: base -= 0x40000CC; size = 4; data = core->dma[1].readDmaDad(2); break; // DMA2DAD (ARM7)
case 0x40000D0:
case 0x40000D1:
case 0x40000D2:
case 0x40000D3: base -= 0x40000D0; size = 4; data = core->dma[1].readDmaCnt(2); break; // DMA2CNT (ARM7)
case 0x40000D4:
case 0x40000D5:
case 0x40000D6:
case 0x40000D7: base -= 0x40000D4; size = 4; data = core->dma[1].readDmaSad(3); break; // DMA3SAD (ARM7)
case 0x40000D8:
case 0x40000D9:
case 0x40000DA:
case 0x40000DB: base -= 0x40000D8; size = 4; data = core->dma[1].readDmaDad(3); break; // DMA3DAD (ARM7)
case 0x40000DC:
case 0x40000DD:
case 0x40000DE:
case 0x40000DF: base -= 0x40000DC; size = 4; data = core->dma[1].readDmaCnt(3); break; // DMA3CNT (ARM7)
case 0x4000100:
case 0x4000101: base -= 0x4000100; size = 2; data = core->timers[1].readTmCntL(0); break; // TM0CNT_L (ARM7)
case 0x4000102:
case 0x4000103: base -= 0x4000102; size = 2; data = core->timers[1].readTmCntH(0); break; // TM0CNT_H (ARM7)
case 0x4000104:
case 0x4000105: base -= 0x4000104; size = 2; data = core->timers[1].readTmCntL(1); break; // TM1CNT_L (ARM7)
case 0x4000106:
case 0x4000107: base -= 0x4000106; size = 2; data = core->timers[1].readTmCntH(1); break; // TM1CNT_H (ARM7)
case 0x4000108:
case 0x4000109: base -= 0x4000108; size = 2; data = core->timers[1].readTmCntL(2); break; // TM2CNT_L (ARM7)
case 0x400010A:
case 0x400010B: base -= 0x400010A; size = 2; data = core->timers[1].readTmCntH(2); break; // TM2CNT_H (ARM7)
case 0x400010C:
case 0x400010D: base -= 0x400010C; size = 2; data = core->timers[1].readTmCntL(3); break; // TM3CNT_L (ARM7)
case 0x400010E:
case 0x400010F: base -= 0x400010E; size = 2; data = core->timers[1].readTmCntH(3); break; // TM3CNT_H (ARM7)
case 0x4000130:
case 0x4000131: base -= 0x4000130; size = 2; data = core->input.readKeyInput(); break; // KEYINPUT
case 0x4000136:
case 0x4000137: base -= 0x4000136; size = 2; data = core->input.readExtKeyIn(); break; // EXTKEYIN
case 0x4000138: base -= 0x4000138; size = 1; data = core->rtc.readRtc(); break; // RTC
case 0x4000180:
case 0x4000181: base -= 0x4000180; size = 2; data = core->ipc.readIpcSync(1); break; // IPCSYNC (ARM7)
case 0x4000184:
case 0x4000185: base -= 0x4000184; size = 2; data = core->ipc.readIpcFifoCnt(1); break; // IPCFIFOCNT (ARM7)
case 0x40001A0:
case 0x40001A1: base -= 0x40001A0; size = 2; data = core->cartridge.readAuxSpiCnt(1); break; // AUXSPICNT (ARM7)
case 0x40001A2: base -= 0x40001A2; size = 1; data = core->cartridge.readAuxSpiData(1); break; // AUXSPIDATA (ARM7)
case 0x40001A4:
case 0x40001A5:
case 0x40001A6:
case 0x40001A7: base -= 0x40001A4; size = 4; data = core->cartridge.readRomCtrl(1); break; // ROMCTRL (ARM7)
case 0x40001C0:
case 0x40001C1: base -= 0x40001C0; size = 2; data = core->spi.readSpiCnt(); break; // SPICNT
case 0x40001C2: base -= 0x40001C2; size = 1; data = core->spi.readSpiData(); break; // SPIDATA
case 0x4000208: base -= 0x4000208; size = 1; data = core->interpreter[1].readIme(); break; // IME (ARM7)
case 0x4000210:
case 0x4000211:
case 0x4000212:
case 0x4000213: base -= 0x4000210; size = 4; data = core->interpreter[1].readIe(); break; // IE (ARM7)
case 0x4000214:
case 0x4000215:
case 0x4000216:
case 0x4000217: base -= 0x4000214; size = 4; data = core->interpreter[1].readIrf(); break; // IF (ARM7)
case 0x4000240: base -= 0x4000240; size = 1; data = readVramStat(); break; // VRAMSTAT
case 0x4000241: base -= 0x4000241; size = 1; data = readWramCnt(); break; // WRAMSTAT
case 0x4000300: base -= 0x4000300; size = 1; data = core->interpreter[1].readPostFlg(); break; // POSTFLG (ARM7)
case 0x4000301: base -= 0x4000301; size = 1; data = readHaltCnt(); break; // HALTCNT
/*case 0x4000400:
case 0x4000401:
case 0x4000402:
case 0x4000403: base -= 0x4000400; size = 4; data = core->spu.readSoundCnt(0); break; // SOUND0CNT
case 0x4000410:
case 0x4000411:
case 0x4000412:
case 0x4000413: base -= 0x4000410; size = 4; data = core->spu.readSoundCnt(1); break; // SOUND1CNT
case 0x4000420:
case 0x4000421:
case 0x4000422:
case 0x4000423: base -= 0x4000420; size = 4; data = core->spu.readSoundCnt(2); break; // SOUND2CNT
case 0x4000430:
case 0x4000431:
case 0x4000432:
case 0x4000433: base -= 0x4000430; size = 4; data = core->spu.readSoundCnt(3); break; // SOUND3CNT
case 0x4000440:
case 0x4000441:
case 0x4000442:
case 0x4000443: base -= 0x4000440; size = 4; data = core->spu.readSoundCnt(4); break; // SOUND4CNT
case 0x4000450:
case 0x4000451:
case 0x4000452:
case 0x4000453: base -= 0x4000450; size = 4; data = core->spu.readSoundCnt(5); break; // SOUND5CNT
case 0x4000460:
case 0x4000461:
case 0x4000462:
case 0x4000463: base -= 0x4000460; size = 4; data = core->spu.readSoundCnt(6); break; // SOUND6CNT
case 0x4000470:
case 0x4000471:
case 0x4000472:
case 0x4000473: base -= 0x4000470; size = 4; data = core->spu.readSoundCnt(7); break; // SOUND7CNT
case 0x4000480:
case 0x4000481:
case 0x4000482:
case 0x4000483: base -= 0x4000480; size = 4; data = core->spu.readSoundCnt(8); break; // SOUND8CNT
case 0x4000490:
case 0x4000491:
case 0x4000492:
case 0x4000493: base -= 0x4000490; size = 4; data = core->spu.readSoundCnt(9); break; // SOUND9CNT
case 0x40004A0:
case 0x40004A1:
case 0x40004A2:
case 0x40004A3: base -= 0x40004A0; size = 4; data = core->spu.readSoundCnt(10); break; // SOUND10CNT
case 0x40004B0:
case 0x40004B1:
case 0x40004B2:
case 0x40004B3: base -= 0x40004B0; size = 4; data = core->spu.readSoundCnt(11); break; // SOUND11CNT
case 0x40004C0:
case 0x40004C1:
case 0x40004C2:
case 0x40004C3: base -= 0x40004C0; size = 4; data = core->spu.readSoundCnt(12); break; // SOUND12CNT
case 0x40004D0:
case 0x40004D1:
case 0x40004D2:
case 0x40004D3: base -= 0x40004D0; size = 4; data = core->spu.readSoundCnt(13); break; // SOUND13CNT
case 0x40004E0:
case 0x40004E1:
case 0x40004E2:
case 0x40004E3: base -= 0x40004E0; size = 4; data = core->spu.readSoundCnt(14); break; // SOUND14CNT
case 0x40004F0:
case 0x40004F1:
case 0x40004F2:
case 0x40004F3: base -= 0x40004F0; size = 4; data = core->spu.readSoundCnt(15); break; // SOUND15CNT
case 0x4000500:
case 0x4000501: base -= 0x4000500; size = 2; data = core->spu.readMainSoundCnt(); break; // SOUNDCNT*/
case 0x4000504:
case 0x4000505: base -= 0x4000504; size = 2; data = core->spu.readSoundBias(); break; // SOUNDBIAS
case 0x4000508: base -= 0x4000508; size = 1; data = core->spu.readSndCapCnt(0); break; // SNDCAP0CNT
case 0x4000509: base -= 0x4000509; size = 1; data = core->spu.readSndCapCnt(1); break; // SNDCAP1CNT
case 0x4000510:
case 0x4000511:
case 0x4000512:
case 0x4000513: base -= 0x4000510; size = 4; data = core->spu.readSndCapDad(0); break; // SNDCAP0DAD
case 0x4000518:
case 0x4000519:
case 0x400051A:
case 0x400051B: base -= 0x4000518; size = 4; data = core->spu.readSndCapDad(1); break; // SNDCAP1DAD
case 0x4100000:
case 0x4100001:
case 0x4100002:
case 0x4100003: base -= 0x4100000; size = 4; data = core->ipc.readIpcFifoRecv(1); break; // IPCFIFORECV (ARM7)
case 0x4100010:
case 0x4100011:
case 0x4100012:
case 0x4100013: base -= 0x4100010; size = 4; data = core->cartridge.readRomDataIn(1); break; // ROMDATAIN (ARM7)
/* case 0x4800006:
case 0x4800007: base -= 0x4800006; size = 2; data = core->wifi.readWModeWep(); break; // W_MODE_WEP
case 0x4800010:
case 0x4800011: base -= 0x4800010; size = 2; data = core->wifi.readWIrf(); break; // W_IF
case 0x4800012: