-
Notifications
You must be signed in to change notification settings - Fork 3
/
apu.h
81 lines (65 loc) · 1.77 KB
/
apu.h
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
#pragma once
#include "types.h"
#define APU_N_PER_TICK CONFIG_APU_N_PER_TICK
#if CONFIG_APU_MONO
#define APU_N_CHANNELS 1
#else
#define APU_N_CHANNELS 2
#endif
struct apu_ch_t
{
r16 ctr;
r16 _unused2;
r8 NR_RAW[5];
r8 _unused[1];
r8 sample_no;
r8 sweep_ctr;
r8 length_ctr;
r8 vol;
r16 raw;
};
struct apu_t
{
struct apu_ch_t ch[4];
var MASTER_CFG;
var CTR_INT;
var CTR_INT_FRAC;
var CTR_DIV;
var outbuf_pos;
r8 WVRAM[16];
s16* outbuf;
word outbuf_size; // must be multiple of 2
s16 outbuf_downsample[APU_N_CHANNELS * APU_N_PER_TICK];
};
typedef struct apu_t apu_t;
void apu_reset(apu_t* __restrict pp);
void apu_initialize(apu_t* __restrict pp);
void apu_write(apu_t* __restrict pp, word addr, word data);
word apu_read(apu_t* __restrict pp, word addr);
void apu_write_wave(apu_t* __restrict pp, word addr, word data);
word apu_read_wave(apu_t* __restrict pp, word addr);
void apu_render_faster(apu_t* __restrict pp, s16* outbuf, word ncounts);
void apu_render(apu_t* __restrict pp, s16* outbuf, word ncounts);
void apu_tick_internal_internals(apu_t* __restrict pp);
void apu_tick_internal(apu_t* __restrict pp);
PGB_FUNC static inline void apu_tick(apu_t* __restrict pp, word ncycles, wbool render)
{
if(pp->MASTER_CFG & (1 << 23))
{
pp->CTR_INT_FRAC += ncycles;
while(pp->CTR_INT_FRAC >= APU_N_PER_TICK)
{
pp->CTR_INT_FRAC -= APU_N_PER_TICK;
if(!render)
apu_tick_internal_internals(pp);
else
apu_tick_internal(pp);
pp->CTR_INT += APU_N_PER_TICK;
pp->CTR_DIV += APU_N_PER_TICK;
}
}
else
{
pp->CTR_DIV += ncycles;
}
}