summaryrefslogtreecommitdiff
path: root/src/Dolphin/dsp/dsp.c
blob: cab7a390a7014bf194f0bb0c2ad700bd31f452a2 (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
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
#include "dolphin/dsp.h"
#include "dolphin/os.h"

#include "dolphin/dsp_regs.h"

#ifdef __cplusplus
extern "C" {
#endif

static const char* __DSPVersion =
    "<< Dolphin SDK - DSP\trelease build: Sep  5 2002 05:35:13 (0x2301) >>";

static s32 __DSP_init_flag = 0;
extern DSPTaskInfo* __DSP_tmp_task;
extern DSPTaskInfo* __DSP_last_task;
extern DSPTaskInfo* __DSP_first_task;
extern DSPTaskInfo* __DSP_curr_task;

extern void __DSPHandler(__OSInterrupt, OSContext*);
extern void __DSP_debug_printf(const char* fmt, ...);
extern void __DSP_boot_task(DSPTaskInfo* task);

u32 DSPCheckMailToDSP(void) { return (__DSPRegs[0] >> 0xF) & 1; }

u32 DSPCheckMailFromDSP(void) { return (__DSPRegs[2] >> 0xF) & 1; }

u32 DSPReadMailFromDSP() {
  u16 reg1;
  u16 reg2;
  reg1 = __DSPRegs[2];
  reg2 = __DSPRegs[3];
  return reg1 << 16 | reg2;
}

void DSPSendMailToDSP(u32 mail) {
  __DSPRegs[0] = mail >> 16;
  __DSPRegs[1] = mail;
}

void DSPInit(void) {
  u32 oldInt;
  u16 reg;
  __DSP_debug_printf("DSPInit(): Build Date: %s %s\n", "Sep  5 2002", "05:35:13");

  if (__DSP_init_flag == 1) {
    return;
  }
  OSRegisterVersion(__DSPVersion);
  oldInt = OSDisableInterrupts();
  __OSSetInterruptHandler(7, __DSPHandler);
  __OSUnmaskInterrupts(0x1000000);
  reg = __DSPRegs[5];
  reg = (reg & ~0xA8) | 0x800;
  __DSPRegs[5] = reg;
  reg = __DSPRegs[5];
  reg = reg & ~0xAC;
  __DSPRegs[5] = reg;
  __DSP_tmp_task = 0;
  __DSP_curr_task = 0;
  __DSP_last_task = 0;
  __DSP_first_task = 0;
  __DSP_init_flag = 1;
  OSRestoreInterrupts(oldInt);
}

void DSPReset(void) {
  u16 reg;
  u32 oldInt;
  oldInt = OSDisableInterrupts();
  reg = __DSPRegs[5];
  __DSPRegs[5] = (reg & ~0xA8) | 0x801;
  __DSP_init_flag = 0;
  OSRestoreInterrupts(oldInt);
}

void DSPHalt(void) {
  u16 reg;
  u32 oldInt;
  oldInt = OSDisableInterrupts();
  reg = __DSPRegs[5];
  __DSPRegs[5] = (reg & ~0xA8) | 4;
  OSRestoreInterrupts(oldInt);
}

u32 DSPGetDMAStatus(void) { return __DSPRegs[5] & 0x200; }

#ifdef FULL_FRANK
DSPTaskInfo* DSPAddTask(DSPTaskInfo* task) {
  u32 oldInt;
  oldInt = OSDisableInterrupts();
  __DSP_insert_task(task);
  task->state = 0;
  task->flags = 1;
  OSRestoreInterrupts(oldInt);
  if (task == __DSP_first_task) {
    __DSP_boot_task(task);
  }

  return task;
}
#else 
#pragma push
#include "__ppc_eabi_linker.h"
/* clang-format off */
#pragma optimization_level 0
#pragma optimizewithasm off
extern void __DSP_insert_task(DSPTaskInfo* task);
asm DSPTaskInfo* DSPAddTask(DSPTaskInfo* task) {
  nofralloc
  mflr r0
  stw r0, 4(r1)
  stwu r1, -0x18(r1)
  stw r31, 0x14(r1)
  stw r30, 0x10(r1)
  mr r30, r3
  bl OSDisableInterrupts
  addi r31, r3, 0
  addi r3, r30, 0
  bl __DSP_insert_task
  li r0, 0
  stw r0, 0(r30)
  li r0, 1
  addi r3, r31, 0
  stw r0, 8(r30)
  bl OSRestoreInterrupts
  lwz r0, __DSP_first_task
  cmplw r30, r0
  bne lbl_8036FBB4
  mr r3, r30
  bl __DSP_boot_task
lbl_8036FBB4:
  mr r3, r30
  lwz r0, 0x1c(r1)
  lwz r31, 0x14(r1)
  lwz r30, 0x10(r1)
  addi r1, r1, 0x18
  mtlr r0
  blr
}
#pragma pop
#endif
/* clang-format on */
#ifdef __cplusplus
}
#endif