2016-03-30 20:07:55 +00:00
|
|
|
#ifndef apu_h
|
|
|
|
#define apu_h
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
/* Divides nicely and never overflows with 4 channels */
|
|
|
|
#define MAX_CH_AMP 0x1E00
|
|
|
|
#define CH_STEP (0x1E00/0xF)
|
|
|
|
|
2016-06-18 17:29:11 +00:00
|
|
|
#include "save_struct.h"
|
2016-03-30 20:07:55 +00:00
|
|
|
|
|
|
|
struct GB_gameboy_s;
|
|
|
|
typedef struct GB_gameboy_s GB_gameboy_t;
|
|
|
|
|
2016-06-10 12:28:50 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int16_t left;
|
|
|
|
int16_t right;
|
|
|
|
} GB_sample_t;
|
|
|
|
|
2016-03-30 20:07:55 +00:00
|
|
|
/* Not all used on all channels */
|
2016-09-13 13:55:56 +00:00
|
|
|
/* All lengths are in APU ticks */
|
2016-03-30 20:07:55 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
2016-09-13 13:55:56 +00:00
|
|
|
uint32_t phase;
|
2016-09-12 22:21:47 +00:00
|
|
|
uint32_t wave_length;
|
2016-09-13 13:55:56 +00:00
|
|
|
int32_t sound_length;
|
|
|
|
bool stop_on_length;
|
|
|
|
uint8_t duty;
|
2016-03-30 20:07:55 +00:00
|
|
|
int16_t amplitude;
|
|
|
|
int16_t start_amplitude;
|
2016-06-18 17:29:11 +00:00
|
|
|
uint8_t envelope_steps;
|
|
|
|
uint8_t cur_envelope_steps;
|
2016-09-13 13:55:56 +00:00
|
|
|
int8_t envelope_direction;
|
2016-06-18 17:29:11 +00:00
|
|
|
uint8_t sweep_steps;
|
|
|
|
uint8_t cur_sweep_steps;
|
2016-09-13 13:55:56 +00:00
|
|
|
int8_t sweep_direction;
|
2016-06-18 17:29:11 +00:00
|
|
|
uint8_t sweep_shift;
|
2016-03-30 20:07:55 +00:00
|
|
|
bool is_playing;
|
2016-09-12 22:21:47 +00:00
|
|
|
uint16_t NRX3_X4_temp;
|
|
|
|
bool left_on;
|
|
|
|
bool right_on;
|
2016-03-30 20:07:55 +00:00
|
|
|
} GB_apu_channel_t;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
2016-09-12 22:21:47 +00:00
|
|
|
uint8_t apu_cycles;
|
|
|
|
bool global_enable;
|
2016-09-13 13:55:56 +00:00
|
|
|
uint32_t envelope_step_timer;
|
|
|
|
uint32_t sweep_step_timer;
|
2016-06-18 17:29:11 +00:00
|
|
|
int8_t wave_form[32];
|
|
|
|
uint8_t wave_shift;
|
2016-03-30 20:07:55 +00:00
|
|
|
bool wave_enable;
|
|
|
|
uint16_t lfsr;
|
|
|
|
bool lfsr_7_bit;
|
2016-09-20 16:58:30 +00:00
|
|
|
uint8_t left_volume;
|
|
|
|
uint8_t right_volume;
|
2016-09-12 22:21:47 +00:00
|
|
|
GB_apu_channel_t wave_channels[4];
|
2016-03-30 20:07:55 +00:00
|
|
|
} GB_apu_t;
|
|
|
|
|
2016-06-18 17:29:11 +00:00
|
|
|
void GB_apu_copy_buffer(GB_gameboy_t *gb, GB_sample_t *dest, unsigned int count);
|
|
|
|
void GB_apu_write(GB_gameboy_t *gb, uint8_t reg, uint8_t value);
|
|
|
|
uint8_t GB_apu_read(GB_gameboy_t *gb, uint8_t reg);
|
2016-09-13 13:55:56 +00:00
|
|
|
void GB_apu_get_samples_and_update_pcm_regs(GB_gameboy_t *gb, GB_sample_t *samples);
|
2016-06-18 17:29:11 +00:00
|
|
|
void GB_apu_init(GB_gameboy_t *gb);
|
|
|
|
void GB_apu_run(GB_gameboy_t *gb);
|
2016-03-30 20:07:55 +00:00
|
|
|
|
|
|
|
#endif /* apu_h */
|