/*
 * 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 YM2413_H
#define YM2413_H

/* Approximate YM2413 sample rate (Hz)
   This accounts for the fact that emulation is run slightly faster than a real
   system, at 60.0Hz vs 59.922743Hz.

   The true sample rate on real hardware is ~49715.903Hz.
    3579545 / 72 = 49715.903
    49715.903 / 59.922743 = 829.666667 samples per frame

   Therefore, to compensate:
    x / 60.0 = 829.666667
    x = 49780
*/
#define SAMPLERATE_YM2413 49780

typedef struct ym2413patchst_t {
    uint32_t TL, FB, EG, ML, AR, DR, SL, RR, KR, KL, AM, PM, WS;
} ym2413patchst_t;

typedef struct _ym2413slotst_t {
    uint8_t number;
    uint8_t type;
    int32_t output[2];
    uint32_t pg_phase;
    uint32_t pg_out;
    uint8_t pg_keep;
    uint16_t blk_fnum;
    uint16_t fnum;
    uint8_t blk;
    uint8_t eg_state;
    int32_t volume;
    uint8_t key_flag;
    uint8_t sus_flag;
    uint16_t tll;
    uint8_t rks;
    uint8_t eg_rate_h;
    uint8_t eg_rate_l;
    uint32_t eg_shift;
    uint32_t eg_out;
    uint32_t update_requests;
} ym2413slotst_t;

typedef struct _ym2413st_t {
    uint32_t adr;
    uint8_t reg[0x40];
    uint8_t test_flag;
    uint32_t slot_key_status;
    uint8_t rhythm_mode;
    uint32_t eg_counter;
    uint32_t pm_phase;
    int32_t am_phase;
    uint8_t lfo_am;
    uint32_t noise;
    uint8_t short_noise;
    int32_t patch_number[9];
    uint32_t mask;
    int16_t ch_out[14];
    int16_t mix_out[2];
    ym2413slotst_t slot[18];
    ym2413patchst_t patch[19*2];
} ym2413st_t;

int16_t* ym2413_get_buffer(void);
void ym2413_init(void);
void ym2413_deinit(void);
void ym2413_disable(void);
void ym2413_reset(void);
void ym2413_wr(uint8_t port, uint8_t data);
size_t ym2413_exec(void);

void ym2413_state_load(uint8_t*);
void ym2413_state_save(uint8_t*);

#endif
