From 6fd10cdacb5cbe47a4fc339c20a733d4a9a384a1 Mon Sep 17 00:00:00 2001 From: Takamichi Horikawa Date: Sat, 26 Nov 2016 20:57:57 +0900 Subject: initial --- libopna/opnatimer.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 libopna/opnatimer.c (limited to 'libopna/opnatimer.c') diff --git a/libopna/opnatimer.c b/libopna/opnatimer.c new file mode 100644 index 0000000..195e426 --- /dev/null +++ b/libopna/opnatimer.c @@ -0,0 +1,79 @@ +#include "opnatimer.h" +#include "opna.h" + +enum { + TIMERB_SHIFT = 4, + TIMERB_BITS = 8 + TIMERB_SHIFT, +}; + +void opna_timer_reset(struct opna_timer *timer, struct opna *opna) { + timer->opna = opna; + timer->status = 0; + timer->interrupt_cb = 0; + timer->interrupt_userptr = 0; + timer->mix_cb = 0; + timer->mix_userptr = 0; + timer->timerb = 0; + timer->timerb_load = false; + timer->timerb_enable = false; + timer->timerb_cnt = 0; +} + +uint8_t opna_timer_status(const struct opna_timer *timer) { + return timer->status; +} + +void opna_timer_set_int_callback(struct opna_timer *timer, opna_timer_int_cb_t func, void *userptr) { + timer->interrupt_cb = func; + timer->interrupt_userptr = userptr; +} + +void opna_timer_set_mix_callback(struct opna_timer *timer, opna_timer_mix_cb_t func, void *userptr) { + timer->mix_cb = func; + timer->mix_userptr = userptr; +} + +void opna_timer_writereg(struct opna_timer *timer, unsigned reg, unsigned val) { + val &= 0xff; + opna_writereg(timer->opna, reg, val); + switch (reg) { + case 0x26: + timer->timerb = val; + timer->timerb_cnt = timer->timerb << TIMERB_SHIFT; + break; + case 0x27: + timer->timerb_load = val & (1<<1); + timer->timerb_enable = val & (1<<3); + if (val & (1<<5)) { + //timer->timerb_cnt = timer->timerb << TIMERB_SHIFT; + timer->status &= ~(1<<1); + } + } +} + +void opna_timer_mix(struct opna_timer *timer, int16_t *buf, unsigned samples) { + do { + unsigned generate_samples = samples; + if (timer->timerb_enable) { + unsigned timerb_samples = (1<timerb_cnt; + if (timerb_samples < generate_samples) { + generate_samples = timerb_samples; + } + } + opna_mix(timer->opna, buf, generate_samples); + if (timer->mix_cb) { + timer->mix_cb(timer->mix_userptr, buf, generate_samples); + } + buf += generate_samples*2; + samples -= generate_samples; + if (timer->timerb_load) { + timer->timerb_cnt = (timer->timerb_cnt + generate_samples) & ((1<timerb_cnt && timer->timerb_enable) { + if (!(timer->status & (1<<1))) { + timer->status |= (1<<1); + timer->interrupt_cb(timer->interrupt_userptr); + } + } + } + } while (samples); +} -- cgit v1.2.3