Skip to content

Commit dda8ec0

Browse files
Allow Teakra to either own DSP memory or have the user provide their own (#66)
* Move ownership of DSP memory to user Co-Authored-By: TheTurtle <47210458+raphaelthegreat@users.noreply.github.com> * Allow SharedMemory to be owned by either the user or Teakra, fix tests * Fix C bindings * Address comments --------- Co-authored-by: TheTurtle <47210458+raphaelthegreat@users.noreply.github.com>
1 parent 3247d54 commit dda8ec0

File tree

5 files changed

+44
-25
lines changed

5 files changed

+44
-25
lines changed

include/teakra/teakra.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,23 @@ struct AHBMCallback {
1919
std::function<void(std::uint32_t address, std::uint32_t value)> write32;
2020
};
2121

22+
struct UserConfig {
23+
// DSP memory. By default set to nullptr. If it stays nullptr then Teakra will create its own
24+
// DSP memory and retain ownership of it. Otherwise, the user will own it.
25+
std::uint8_t* dsp_memory = nullptr;
26+
};
27+
28+
static constexpr std::uint32_t DspMemorySize = 0x80000;
29+
2230
class Teakra {
2331
public:
24-
Teakra();
32+
Teakra(const UserConfig& config);
2533
~Teakra();
2634

2735
void Reset();
2836

29-
std::array<std::uint8_t, 0x80000>& GetDspMemory();
30-
const std::array<std::uint8_t, 0x80000>& GetDspMemory() const;
37+
uint8_t* GetDspMemory();
38+
const uint8_t* GetDspMemory() const;
3139

3240
RegisterState& GetRegisterState();
3341
const RegisterState& GetRegisterState() const;

src/shared_memory.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
11
#pragma once
22
#include <array>
3-
#include <cstdio>
3+
#include <memory>
4+
#include <optional>
45
#include "common_types.h"
56

67
namespace Teakra {
78
struct SharedMemory {
8-
std::array<u8, 0x80000> raw{};
9+
// We allocate our own memory if the user doesn't supply their own
10+
std::unique_ptr<std::array<u8, 0x80000>> own_memory;
11+
// Points to either own own memory or user-supplied memory
12+
u8* raw;
13+
14+
SharedMemory(u8* mem = nullptr) : raw{mem} {
15+
if (mem == nullptr) {
16+
own_memory = std::make_unique<std::array<u8, 0x80000>>();
17+
raw = own_memory->data();
18+
}
19+
}
20+
921
u16 ReadWord(u32 word_address) const {
1022
u32 byte_address = word_address * 2;
1123
u8 low = raw[byte_address];

src/teakra.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include <array>
2-
#include <atomic>
2+
#include <cstring>
33
#include "ahbm.h"
44
#include "apbp.h"
55
#include "btdmp.h"
@@ -30,7 +30,7 @@ struct Teakra::Impl {
3030
MemoryInterface memory_interface{shared_memory, miu};
3131
Processor processor{core_timing, memory_interface};
3232

33-
Impl() {
33+
Impl(u8* dsp_memory) : shared_memory{dsp_memory} {
3434
memory_interface.SetMMIO(mmio);
3535
using namespace std::placeholders;
3636
icu.SetInterruptHandler(std::bind(&Processor::SignalInterrupt, &processor, _1),
@@ -51,7 +51,7 @@ struct Teakra::Impl {
5151
}
5252

5353
void Reset() {
54-
shared_memory.raw.fill(0);
54+
std::memset(shared_memory.raw, 0, DspMemorySize);
5555
miu.Reset();
5656
apbp_from_cpu.Reset();
5757
apbp_from_dsp.Reset();
@@ -65,18 +65,18 @@ struct Teakra::Impl {
6565
}
6666
};
6767

68-
Teakra::Teakra() : impl(new Impl) {}
68+
Teakra::Teakra(const UserConfig& config) : impl(std::make_unique<Impl>(config.dsp_memory)) {}
6969
Teakra::~Teakra() = default;
7070

7171
void Teakra::Reset() {
7272
impl->Reset();
7373
}
7474

75-
std::array<std::uint8_t, 0x80000>& Teakra::GetDspMemory() {
75+
uint8_t* Teakra::GetDspMemory() {
7676
return impl->shared_memory.raw;
7777
}
7878

79-
const std::array<std::uint8_t, 0x80000>& Teakra::GetDspMemory() const {
79+
const uint8_t* Teakra::GetDspMemory() const {
8080
return impl->shared_memory.raw;
8181
}
8282

src/teakra_c.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
extern "C" {
55

66
struct TeakraObject {
7-
Teakra::Teakra teakra;
7+
Teakra::UserConfig config;
8+
Teakra::Teakra teakra{config};
89
};
910

1011
TeakraContext* Teakra_Create() {
@@ -20,7 +21,7 @@ void Teakra_Reset(TeakraContext* context) {
2021
}
2122

2223
uint8_t* Teakra_GetDspMemory(TeakraContext* context) {
23-
return context->teakra.GetDspMemory().data();
24+
return context->teakra.GetDspMemory();
2425
}
2526

2627
int Teakra_SendDataIsEmpty(const TeakraContext* context, uint8_t index) {
@@ -94,7 +95,7 @@ void Teakra_MMIOWrite(TeakraContext* context, uint16_t address, uint16_t value)
9495
uint16_t Teakra_DMAChan0GetSrcHigh(TeakraContext* context) {
9596
return context->teakra.DMAChan0GetSrcHigh();
9697
}
97-
uint16_t Teakra_DMAChan0GetDstHigh(TeakraContext* context){
98+
uint16_t Teakra_DMAChan0GetDstHigh(TeakraContext* context) {
9899
return context->teakra.DMAChan0GetDstHigh();
99100
}
100101

@@ -125,11 +126,10 @@ void Teakra_Run(TeakraContext* context, unsigned cycle) {
125126
context->teakra.Run(cycle);
126127
}
127128

128-
void Teakra_SetAHBMCallback(TeakraContext* context,
129-
Teakra_AHBMReadCallback8 read8 , Teakra_AHBMWriteCallback8 write8 ,
130-
Teakra_AHBMReadCallback16 read16, Teakra_AHBMWriteCallback16 write16,
131-
Teakra_AHBMReadCallback32 read32, Teakra_AHBMWriteCallback32 write32,
132-
void* userdata) {
129+
void Teakra_SetAHBMCallback(TeakraContext* context, Teakra_AHBMReadCallback8 read8,
130+
Teakra_AHBMWriteCallback8 write8, Teakra_AHBMReadCallback16 read16,
131+
Teakra_AHBMWriteCallback16 write16, Teakra_AHBMReadCallback32 read32,
132+
Teakra_AHBMWriteCallback32 write32, void* userdata) {
133133
Teakra::AHBMCallback callback;
134134
callback.read8 = [=](uint32_t address) { return read8(userdata, address); };
135135
callback.write8 = [=](uint32_t address, uint8_t value) { write8(userdata, address, value); };
@@ -140,7 +140,6 @@ void Teakra_SetAHBMCallback(TeakraContext* context,
140140
context->teakra.SetAHBMCallback(callback);
141141
}
142142

143-
144143
void Teakra_SetAudioCallback(TeakraContext* context, Teakra_AudioCallback callback,
145144
void* userdata) {
146145
context->teakra.SetAudioCallback(

tests/dma.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,14 @@ TEST_CASE("DMA + AHBM test", "[dma]") {
3333
},
3434
[&fcram](u32 address) -> u32 {
3535
REQUIRE(address >= 0x20000000);
36-
return fcram[address - 0x20000000] | ((u32)fcram[address - 0x20000000 + 1] << 8)
37-
| ((u32)fcram[address - 0x20000000 + 2] << 16) | ((u32)fcram[address - 0x20000000 + 3] << 24);
36+
return fcram[address - 0x20000000] | ((u32)fcram[address - 0x20000000 + 1] << 8) |
37+
((u32)fcram[address - 0x20000000 + 2] << 16) |
38+
((u32)fcram[address - 0x20000000 + 3] << 24);
3839
},
3940
[&fcram](u32 address, u32 v) {
4041
REQUIRE(address >= 0x20000000);
4142
fcram[address - 0x20000000 + 0] = (u8)v;
42-
fcram[address - 0x20000000 + 1] = (u8)(v >> 8);
43+
fcram[address - 0x20000000 + 1] = (u8)(v >> 8);
4344
fcram[address - 0x20000000 + 2] = (u8)(v >> 16);
4445
fcram[address - 0x20000000 + 3] = (u8)(v >> 24);
4546
});
@@ -50,8 +51,7 @@ TEST_CASE("DMA + AHBM test", "[dma]") {
5051
}
5152

5253
auto GetDspTestArea = [&shared_memory]() {
53-
return std::vector<u8>(shared_memory.raw.begin() + 0x40000,
54-
shared_memory.raw.begin() + 0x40000 + 0x80);
54+
return std::vector<u8>(shared_memory.raw + 0x40000, shared_memory.raw + 0x40000 + 0x80);
5555
};
5656

5757
auto GenerateExpected = [](const std::string& str, u8 base = 0) {

0 commit comments

Comments
 (0)