1 #include "teakra/teakra.h"
2 #include "teakra/teakra_c.h"
3 
4 extern "C" {
5 
6 struct TeakraObject {
7     Teakra::Teakra teakra;
8 };
9 
Teakra_Create()10 TeakraContext* Teakra_Create() {
11     return new TeakraContext;
12 }
13 
Teakra_Destroy(TeakraContext * context)14 void Teakra_Destroy(TeakraContext* context) {
15     delete context;
16 }
17 
Teakra_Reset(TeakraContext * context)18 void Teakra_Reset(TeakraContext* context) {
19     context->teakra.Reset();
20 }
21 
Teakra_GetDspMemory(TeakraContext * context)22 uint8_t* Teakra_GetDspMemory(TeakraContext* context) {
23     return context->teakra.GetDspMemory().data();
24 }
25 
Teakra_SendDataIsEmpty(const TeakraContext * context,uint8_t index)26 int Teakra_SendDataIsEmpty(const TeakraContext* context, uint8_t index) {
27     return context->teakra.SendDataIsEmpty(index);
28 }
29 
Teakra_SendData(TeakraContext * context,uint8_t index,uint16_t value)30 void Teakra_SendData(TeakraContext* context, uint8_t index, uint16_t value) {
31     context->teakra.SendData(index, value);
32 }
33 
Teakra_RecvDataIsReady(const TeakraContext * context,uint8_t index)34 int Teakra_RecvDataIsReady(const TeakraContext* context, uint8_t index) {
35     return context->teakra.RecvDataIsReady(index);
36 }
37 
Teakra_RecvData(TeakraContext * context,uint8_t index)38 uint16_t Teakra_RecvData(TeakraContext* context, uint8_t index) {
39     return context->teakra.RecvData(index);
40 }
Teakra_PeekRecvData(TeakraContext * context,uint8_t index)41 uint16_t Teakra_PeekRecvData(TeakraContext* context, uint8_t index) {
42     return context->teakra.PeekRecvData(index);
43 }
44 
Teakra_SetRecvDataHandler(TeakraContext * context,uint8_t index,Teakra_InterruptCallback handler,void * userdata)45 void Teakra_SetRecvDataHandler(TeakraContext* context, uint8_t index,
46                                Teakra_InterruptCallback handler, void* userdata) {
47     context->teakra.SetRecvDataHandler(index, [=]() { handler(userdata); });
48 }
49 
Teakra_SetSemaphore(TeakraContext * context,uint16_t value)50 void Teakra_SetSemaphore(TeakraContext* context, uint16_t value) {
51     context->teakra.SetSemaphore(value);
52 }
Teakra_ClearSemaphore(TeakraContext * context,uint16_t value)53 void Teakra_ClearSemaphore(TeakraContext* context, uint16_t value) {
54     context->teakra.ClearSemaphore(value);
55 }
Teakra_MaskSemaphore(TeakraContext * context,uint16_t value)56 void Teakra_MaskSemaphore(TeakraContext* context, uint16_t value) {
57     context->teakra.MaskSemaphore(value);
58 }
59 
Teakra_SetSemaphoreHandler(TeakraContext * context,Teakra_InterruptCallback handler,void * userdata)60 void Teakra_SetSemaphoreHandler(TeakraContext* context, Teakra_InterruptCallback handler,
61                                 void* userdata) {
62     context->teakra.SetSemaphoreHandler([=]() { handler(userdata); });
63 }
64 
Teakra_GetSemaphore(const TeakraContext * context)65 uint16_t Teakra_GetSemaphore(const TeakraContext* context) {
66     return context->teakra.GetSemaphore();
67 }
68 
Teakra_ProgramRead(TeakraContext * context,uint32_t address)69 uint16_t Teakra_ProgramRead(TeakraContext* context, uint32_t address) {
70     return context->teakra.ProgramRead(address);
71 }
Teakra_ProgramWrite(TeakraContext * context,uint32_t address,uint16_t value)72 void Teakra_ProgramWrite(TeakraContext* context, uint32_t address, uint16_t value) {
73     context->teakra.ProgramWrite(address, value);
74 }
Teakra_DataRead(TeakraContext * context,uint16_t address,bool bypass_mmio)75 uint16_t Teakra_DataRead(TeakraContext* context, uint16_t address, bool bypass_mmio) {
76     return context->teakra.DataRead(address, bypass_mmio);
77 }
Teakra_DataWrite(TeakraContext * context,uint16_t address,uint16_t value,bool bypass_mmio)78 void Teakra_DataWrite(TeakraContext* context, uint16_t address, uint16_t value, bool bypass_mmio) {
79     context->teakra.DataWrite(address, value, bypass_mmio);
80 }
Teakra_DataReadA32(TeakraContext * context,uint32_t address)81 uint16_t Teakra_DataReadA32(TeakraContext* context, uint32_t address) {
82     return context->teakra.DataReadA32(address);
83 }
Teakra_DataWriteA32(TeakraContext * context,uint32_t address,uint16_t value)84 void Teakra_DataWriteA32(TeakraContext* context, uint32_t address, uint16_t value) {
85     context->teakra.DataWriteA32(address, value);
86 }
Teakra_MMIORead(TeakraContext * context,uint16_t address)87 uint16_t Teakra_MMIORead(TeakraContext* context, uint16_t address) {
88     return context->teakra.MMIORead(address);
89 }
Teakra_MMIOWrite(TeakraContext * context,uint16_t address,uint16_t value)90 void Teakra_MMIOWrite(TeakraContext* context, uint16_t address, uint16_t value) {
91     context->teakra.MMIOWrite(address, value);
92 }
93 
Teakra_DMAChan0GetSrcHigh(TeakraContext * context)94 uint16_t Teakra_DMAChan0GetSrcHigh(TeakraContext* context) {
95     return context->teakra.DMAChan0GetSrcHigh();
96 }
Teakra_DMAChan0GetDstHigh(TeakraContext * context)97 uint16_t Teakra_DMAChan0GetDstHigh(TeakraContext* context){
98     return context->teakra.DMAChan0GetDstHigh();
99 }
100 
Teakra_AHBMGetUnitSize(TeakraContext * context,uint16_t i)101 uint16_t Teakra_AHBMGetUnitSize(TeakraContext* context, uint16_t i) {
102     return context->teakra.AHBMGetUnitSize(i);
103 }
Teakra_AHBMGetDirection(TeakraContext * context,uint16_t i)104 uint16_t Teakra_AHBMGetDirection(TeakraContext* context, uint16_t i) {
105     return context->teakra.AHBMGetDirection(i);
106 }
Teakra_AHBMGetDmaChannel(TeakraContext * context,uint16_t i)107 uint16_t Teakra_AHBMGetDmaChannel(TeakraContext* context, uint16_t i) {
108     return context->teakra.AHBMGetDmaChannel(i);
109 }
110 
Teakra_AHBMRead16(TeakraContext * context,uint32_t addr)111 uint16_t Teakra_AHBMRead16(TeakraContext* context, uint32_t addr) {
112     return context->teakra.AHBMRead16(addr);
113 }
Teakra_AHBMWrite16(TeakraContext * context,uint32_t addr,uint16_t value)114 void Teakra_AHBMWrite16(TeakraContext* context, uint32_t addr, uint16_t value) {
115     context->teakra.AHBMWrite16(addr, value);
116 }
Teakra_AHBMRead32(TeakraContext * context,uint32_t addr)117 uint16_t Teakra_AHBMRead32(TeakraContext* context, uint32_t addr) {
118     return context->teakra.AHBMRead32(addr);
119 }
Teakra_AHBMWrite32(TeakraContext * context,uint32_t addr,uint32_t value)120 void Teakra_AHBMWrite32(TeakraContext* context, uint32_t addr, uint32_t value) {
121     context->teakra.AHBMWrite32(addr, value);
122 }
123 
Teakra_Run(TeakraContext * context,unsigned cycle)124 void Teakra_Run(TeakraContext* context, unsigned cycle) {
125     context->teakra.Run(cycle);
126 }
127 
Teakra_SetAHBMCallback(TeakraContext * context,Teakra_AHBMReadCallback8 read8,Teakra_AHBMWriteCallback8 write8,Teakra_AHBMReadCallback16 read16,Teakra_AHBMWriteCallback16 write16,Teakra_AHBMReadCallback32 read32,Teakra_AHBMWriteCallback32 write32,void * userdata)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) {
133     Teakra::AHBMCallback callback;
134     callback.read8 = [=](uint32_t address) { return read8(userdata, address); };
135     callback.write8 = [=](uint32_t address, uint8_t value) { write8(userdata, address, value); };
136     callback.read16 = [=](uint32_t address) { return read16(userdata, address); };
137     callback.write16 = [=](uint32_t address, uint16_t value) { write16(userdata, address, value); };
138     callback.read32 = [=](uint32_t address) { return read32(userdata, address); };
139     callback.write32 = [=](uint32_t address, uint32_t value) { write32(userdata, address, value); };
140     context->teakra.SetAHBMCallback(callback);
141 }
142 
143 
Teakra_SetAudioCallback(TeakraContext * context,Teakra_AudioCallback callback,void * userdata)144 void Teakra_SetAudioCallback(TeakraContext* context, Teakra_AudioCallback callback,
145                              void* userdata) {
146     context->teakra.SetAudioCallback(
147         [=](std::array<std::int16_t, 2> samples) { callback(userdata, samples.data()); });
148 }
149 }
150