From 16be4100808e09a94e802adb58bc1c79e5eefd65 Mon Sep 17 00:00:00 2001 From: Takamichi Horikawa Date: Tue, 14 Mar 2017 19:07:57 +0900 Subject: libopna: enable register read --- libopna/opna.c | 5 +++++ libopna/opna.h | 1 + libopna/opnassg.c | 13 ++++++++++--- libopna/opnassg.h | 2 +- libopna/opnatimer.c | 36 ++++++++++++++++++++++++++++++++++-- libopna/opnatimer.h | 3 +++ 6 files changed, 54 insertions(+), 6 deletions(-) (limited to 'libopna') diff --git a/libopna/opna.c b/libopna/opna.c index fb9e24a..10155d0 100644 --- a/libopna/opna.c +++ b/libopna/opna.c @@ -17,6 +17,11 @@ void opna_writereg(struct opna *opna, unsigned reg, unsigned val) { opna_adpcm_writereg(&opna->adpcm, reg, val); } +unsigned opna_readreg(const struct opna *opna, unsigned reg) { + if (reg > 0xfu) return 0xff; + return opna_ssg_readreg(&opna->ssg, reg); +} + void opna_mix(struct opna *opna, int16_t *buf, unsigned samples) { opna_fm_mix(&opna->fm, buf, samples); opna_ssg_mix_55466(&opna->ssg, &opna->resampler, buf, samples); diff --git a/libopna/opna.h b/libopna/opna.h index b5e9d87..7d7d722 100644 --- a/libopna/opna.h +++ b/libopna/opna.h @@ -41,6 +41,7 @@ struct opna { void opna_reset(struct opna *opna); void opna_writereg(struct opna *opna, unsigned reg, unsigned val); +unsigned opna_readreg(const struct opna *opna, unsigned reg); void opna_mix(struct opna *opna, int16_t *buf, unsigned samples); unsigned opna_get_mask(const struct opna *opna); void opna_set_mask(struct opna *opna, unsigned mask); diff --git a/libopna/opnassg.c b/libopna/opnassg.c index 1345502..3c5b108 100644 --- a/libopna/opnassg.c +++ b/libopna/opnassg.c @@ -103,6 +103,11 @@ void opna_ssg_writereg(struct opna_ssg *ssg, unsigned reg, unsigned val) { } } +unsigned opna_ssg_readreg(const struct opna_ssg *ssg, unsigned reg) { + if (reg > 0xfu) return 0xff; + return ssg->regs[reg]; +} + static int opna_ssg_tone_period(const struct opna_ssg *ssg, int chan) { return ssg->regs[0+chan*2] | ((ssg->regs[1+chan*2] & 0xf) << 8); } @@ -173,7 +178,9 @@ void opna_ssg_generate_raw(struct opna_ssg *ssg, int16_t *buf, int samples) { ssg->ch[ch].out = !ssg->ch[ch].out; } if (ssg->mask & (1<opna, reg, val); switch (reg) { + case 0x24: + timer->timera &= ~0xff; + timer->timera |= val; + break; + case 0x25: + timer->timera &= 0xff; + timer->timera |= ((val & 3) << 8); + break; case 0x26: timer->timerb = val; timer->timerb_cnt = timer->timerb << TIMERB_SHIFT; break; case 0x27: + timer->timera_load = val & (1<<0); + timer->timera_enable = val & (1<<2); timer->timerb_load = val & (1<<1); timer->timerb_enable = val & (1<<3); + + if (val & (1<<4)) { + timer->status &= ~(1<<0); + } if (val & (1<<5)) { //timer->timerb_cnt = timer->timerb << TIMERB_SHIFT; timer->status &= ~(1<<1); } } } - +#include +#include void opna_timer_mix(struct opna_timer *timer, int16_t *buf, unsigned samples) { do { unsigned generate_samples = samples; - if (timer->timerb_enable) { + if (timer->timerb_enable && timer->timerb_load) { unsigned timerb_samples = (1<timerb_cnt; if (timerb_samples < generate_samples) { generate_samples = timerb_samples; } } + if (timer->timera_enable && timer->timera_load) { + unsigned timera_samples = (1<timera; + if (timera_samples < generate_samples) { + generate_samples = timera_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->timera_load) { + timer->timera = (timer->timera + generate_samples) & ((1<timera && timer->timera_enable) { + if (!(timer->status & (1<<0))) { + timer->status |= (1<<0); + timer->interrupt_cb(timer->interrupt_userptr); + } + } + timer->timera &= (1<timerb_load) { timer->timerb_cnt = (timer->timerb_cnt + generate_samples) & ((1<timerb_cnt && timer->timerb_enable) { diff --git a/libopna/opnatimer.h b/libopna/opnatimer.h index f3094ba..ad0fe0b 100644 --- a/libopna/opnatimer.h +++ b/libopna/opnatimer.h @@ -20,7 +20,10 @@ struct opna_timer { void *interrupt_userptr; opna_timer_mix_cb_t mix_cb; void *mix_userptr; + uint16_t timera; uint8_t timerb; + bool timera_load; + bool timera_enable; bool timerb_load; bool timerb_enable; uint16_t timerb_cnt; -- cgit v1.2.3