/*
 * Copyright (c) 2021-2022 Rupert Carmichael
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#ifndef SN76496_H
#define SN76496_H

#define SAMPLERATE_PSG 224010 // Approximate PSG sample rate (Hz)

#define NSHIFT 15 // Linear Feedback Shift Register is 16 bits, so shift 15
#define NSHIFT_SG 14 // Linear Feedback Shift Register is 15 bits, so shift 14
#define NTAP 0x0009 // Tapped bits for SMS and later are 0 and 3
#define NTAP_SG 0x0003 // Tapped bits for SG-1000 are 0 and 1

typedef struct _sn76496_t {
    uint8_t clatch; // Channel latch tells which channel's registers to write
    uint8_t attenuator[4]; // Four attenuators control volume on four channels
    uint16_t frequency[3]; // Three frequency registers for Tone Generators
    uint8_t noise; // One register for the Noise Generator
    uint16_t lfsr; // Linear Feedback Shift Register, 15/16 bits (SG-1000/SMS)
    uint16_t counter[4]; // Period Counter
    int16_t output[4]; // Per-channel output volumes for mixing
    uint8_t freqff; // Four bits for four channels, 0 = Positive, 1 = Negative
    uint8_t stctrl; // Stereo Control bits
} sn76496_t;

int16_t* sn76496_get_buffer(void);

void sn76496_init(uint8_t, uint16_t, uint16_t);
void sn76496_disable(void);
void sn76496_wr(uint8_t);
void sn76496_wr_stereo(uint8_t);
size_t sn76496_exec(void);

void sn76496_state_load(uint8_t*);
void sn76496_state_save(uint8_t*);

#endif
