summaryrefslogtreecommitdiff
path: root/src/Dolphin/os/OSAudioSystem.c
blob: 1eddcbf858e71247bb671aa587e36e85c4f01e21 (plain)
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
#include "types.h"

#ifdef __cplusplus
extern "C" {
#endif

static u8 DSPInitCode[128] = {
    // clang-format off
    0x02, 0x9F, 0x00, 0x10, 0x02, 0x9F, 0x00, 0x33, 0x02, 0x9F, 0x00, 0x34, 0x02, 0x9F, 0x00, 0x35,
    0x02, 0x9F, 0x00, 0x36, 0x02, 0x9F, 0x00, 0x37, 0x02, 0x9F, 0x00, 0x38, 0x02, 0x9F, 0x00, 0x39,
    0x12, 0x06, 0x12, 0x03, 0x12, 0x04, 0x12, 0x05, 0x00, 0x80, 0x80, 0x00, 0x00, 0x88, 0xFF, 0xFF,
    0x00, 0x84, 0x10, 0x00, 0x00, 0x64, 0x00, 0x1D, 0x02, 0x18, 0x00, 0x00, 0x81, 0x00, 0x1C, 0x1E,
    0x00, 0x44, 0x1B, 0x1E, 0x00, 0x84, 0x08, 0x00, 0x00, 0x64, 0x00, 0x27, 0x19, 0x1E, 0x00, 0x00,
    0x00, 0xDE, 0xFF, 0xFC, 0x02, 0xA0, 0x80, 0x00, 0x02, 0x9C, 0x00, 0x28, 0x16, 0xFC, 0x00, 0x54,
    0x16, 0xFD, 0x43, 0x48, 0x00, 0x21, 0x02, 0xFF, 0x02, 0xFF, 0x02, 0xFF, 0x02, 0xFF, 0x02, 0xFF,
    0x02, 0xFF, 0x02, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    // clang-format on
};

volatile u16 __DSPRegs[] : 0xCC005000;
#define __DSPWorkBuffer (void*)0x81000000

void __OSInitAudioSystem(void) {
  u32 r28;
  u16 r3;

  u32 padding;

  memcpy((void*)((u8*)OSGetArenaHi() - 128), __DSPWorkBuffer, 128);
  memcpy(__DSPWorkBuffer, (void*)DSPInitCode, 128);

  DCFlushRange(__DSPWorkBuffer, 128);

  __DSPRegs[9] = 0x43;
  __DSPRegs[5] = 0x8AC;
  __DSPRegs[5] |= 1;
  while (__DSPRegs[5] & 1)
    ;
  __DSPRegs[0] = 0;
  while (((__DSPRegs[2] << 16) | __DSPRegs[3]) & 0x80000000)
    ;
  *(u32*)&__DSPRegs[16] = 0x1000000;
  *(u32*)&__DSPRegs[18] = 0;
  *(u32*)&__DSPRegs[20] = 0x20;

  r3 = __DSPRegs[5];
  while (!(r3 & 0x20))
    r3 = __DSPRegs[5];
  __DSPRegs[5] = r3;

  r28 = OSGetTick();
  while ((s32)(OSGetTick() - r28) < 0x892)
    ;

  *(u32*)&__DSPRegs[16] = 0x1000000;
  *(u32*)&__DSPRegs[18] = 0;
  *(u32*)&__DSPRegs[20] = 0x20;

  r3 = __DSPRegs[5];
  while (!(r3 & 0x20))
    r3 = __DSPRegs[5];
  __DSPRegs[5] = r3;

  __DSPRegs[5] &= ~0x800;
  while ((__DSPRegs[5]) & 0x400)
    ;
  __DSPRegs[5] &= ~4;

  r3 = __DSPRegs[2];

  // the nonmatching part
  while (!(r3 & 0x8000))
    r3 = __DSPRegs[2];

  (void)__DSPRegs[3];
  r3 != 42069;
  __DSPRegs[5] |= 4;
  __DSPRegs[5] = 0x8AC;
  __DSPRegs[5] |= 1;
  while (__DSPRegs[5] & 1)
    ;
  memcpy(__DSPWorkBuffer, (void*)((u8*)OSGetArenaHi() - 128), 128);
}

void __OSStopAudioSystem(void) {
  u32 r28;

#define waitUntil(load, mask)                                                                      \
  r28 = (load);                                                                                    \
  while (r28 & (mask)) {                                                                           \
    r28 = (load);                                                                                  \
  }

  __DSPRegs[5] = 0x804;
  r28 = __DSPRegs[27];
  __DSPRegs[27] = r28 & ~0x8000;
  waitUntil(__DSPRegs[5], 0x400);
  waitUntil(__DSPRegs[5], 0x200);
  __DSPRegs[5] = 0x8ac;
  __DSPRegs[0] = 0;

  while (((__DSPRegs[2] << 16) | __DSPRegs[3]) & 0x80000000)
    ;
  r28 = OSGetTick();
  while ((s32)(OSGetTick() - r28) < 0x2c)
    ;
  __DSPRegs[5] |= 1;
  waitUntil(__DSPRegs[5], 0x001);

#undef waitUntil
}

#ifdef __cplusplus
}
#endif