Finished the sound/snd_opl.c rewrite.

This commit is contained in:
OBattler
2020-07-26 02:35:41 +02:00
parent 24926d4b2f
commit 797af21ad9
3 changed files with 49 additions and 59 deletions

View File

@@ -8,16 +8,11 @@
* *
* Definitions for the OPL interface. * Definitions for the OPL interface.
* *
* Version: @(#)snd_opl.h 1.0.3 2020/07/15
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
* TheCollector1995, <mariogplayer@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
* *
* Copyright 2017-2020 Fred N. van Kempen. * Copyright 2017-2020 Fred N. van Kempen.
* Copyright 2016-2019 Miran Grca. * Copyright 2016-2020 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
*/ */
#ifndef SOUND_OPL_H #ifndef SOUND_OPL_H
# define SOUND_OPL_H # define SOUND_OPL_H
@@ -32,12 +27,10 @@ typedef struct {
#else #else
void *opl; void *opl;
#endif #endif
int8_t is_opl3, do_cycles; int8_t flags, pad;
uint16_t port; uint16_t port;
uint8_t status; uint8_t status, timer_ctrl;
uint8_t status_mask;
uint8_t timer_ctrl;
uint16_t timer_count[2], uint16_t timer_count[2],
timer_cur_count[2]; timer_cur_count[2];

View File

@@ -14,19 +14,17 @@
* *
* Authors: Fred N. van Kempen, <decwiz@yahoo.com> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
* TheCollector1995, <mariogplayer@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
* *
* Copyright 2017-2020 Fred N. van Kempen. * Copyright 2017-2020 Fred N. van Kempen.
* Copyright 2016-2019 Miran Grca. * Copyright 2016-2020 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
*/ */
#include <stdio.h> #include <stdarg.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <wchar.h> #include <wchar.h>
#define dbglog sound_card_log #define HAVE_STDARG_H
#include <86box/86box.h> #include <86box/86box.h>
#include <86box/timer.h> #include <86box/timer.h>
#include "cpu.h" #include "cpu.h"
@@ -37,17 +35,24 @@
enum { enum {
STATUS_TIMER_1 = 0x40, FLAG_CYCLES = 0x02,
STATUS_TIMER_2 = 0x20, FLAG_OPL3 = 0x01
STATUS_TIMER_ALL = 0x80
}; };
enum { enum {
CTRL_IRQ_RESET = 0x80, STAT_TMR_OVER = 0x60,
CTRL_TIMER1_MASK = 0x40, STAT_TMR1_OVER = 0x40,
CTRL_TIMER2_MASK = 0x20, STAT_TMR2_OVER = 0x20,
CTRL_TIMER2_CTRL = 0x02, STAT_TMR_ANY = 0x80
CTRL_TIMER1_CTRL = 0x01 };
enum {
CTRL_RESET = 0x80,
CTRL_TMR_MASK = 0x60,
CTRL_TMR1_MASK = 0x40,
CTRL_TMR2_MASK = 0x20,
CTRL_TMR2_START = 0x02,
CTRL_TMR1_START = 0x01
}; };
@@ -71,21 +76,6 @@ opl_log(const char *fmt, ...)
#endif #endif
static void
timer_over(opl_t *dev, int tmr)
{
opl_log("Count wrapped around to zero, reloading timer %i...\n", tmr);
if (tmr == 1) {
dev->status |= STATUS_TIMER_2;
dev->timer_cur_count[1] = dev->timer_count[1];
} else {
dev->status |= STATUS_TIMER_1;
dev->timer_cur_count[0] = dev->timer_count[0];
}
}
static void static void
timer_tick(opl_t *dev, int tmr) timer_tick(opl_t *dev, int tmr)
{ {
@@ -93,8 +83,12 @@ timer_tick(opl_t *dev, int tmr)
opl_log("Ticking timer %i, count now %02X...\n", tmr, dev->timer_cur_count[tmr]); opl_log("Ticking timer %i, count now %02X...\n", tmr, dev->timer_cur_count[tmr]);
if (dev->timer_cur_count[tmr] == 0x00) if (dev->timer_cur_count[tmr] == 0x00) {
timer_over(dev, tmr); dev->status |= ((STAT_TMR1_OVER >> tmr) & ~dev->timer_ctrl);
dev->timer_cur_count[tmr] = dev->timer_count[tmr];
opl_log("Count wrapped around to zero, reloading timer %i (%02X), status = %02X...\n", tmr, (STAT_TMR1_OVER >> tmr), dev->status);
}
timer_on_auto(&dev->timers[tmr], (tmr == 1) ? 320.0 : 80.0); timer_on_auto(&dev->timers[tmr], (tmr == 1) ? 320.0 : 80.0);
} }
@@ -138,9 +132,9 @@ opl_read(opl_t *dev, uint16_t port)
uint8_t ret = 0xff; uint8_t ret = 0xff;
if ((port & 0x0003) == 0x0000) { if ((port & 0x0003) == 0x0000) {
ret = ((dev->status & dev->status_mask) | (dev->is_opl3 ? 0x00 : 0x06)); ret = dev->status;
if (dev->status & dev->status_mask) if (dev->status & STAT_TMR_OVER)
ret |= STATUS_TIMER_ALL; ret |= STAT_TMR_ANY;
} }
return ret; return ret;
@@ -165,22 +159,21 @@ opl_write(opl_t *dev, uint16_t port, uint8_t val)
break; break;
case 0x04: /* Timer control */ case 0x04: /* Timer control */
if (val & CTRL_IRQ_RESET) { if (val & CTRL_RESET) {
opl_log("Resetting timer status...\n"); opl_log("Resetting timer status...\n");
dev->status &= ~(STATUS_TIMER_1 | STATUS_TIMER_2); dev->status &= ~STAT_TMR_OVER;
} else { } else {
timer_control(dev, 0, val & CTRL_TIMER1_CTRL); timer_control(dev, 0, val & CTRL_TMR1_START);
timer_control(dev, 1, val & CTRL_TIMER2_CTRL); timer_control(dev, 1, val & CTRL_TMR2_START);
dev->timer_ctrl = val; dev->timer_ctrl = val;
dev->status_mask = (CTRL_TIMER1_MASK | CTRL_TIMER2_MASK) & ~(val & (CTRL_TIMER1_MASK | CTRL_TIMER2_MASK)); opl_log("Status mask now %02X (val = %02X)\n", (val & ~CTRL_TMR_MASK) & CTRL_TMR_MASK, val);
opl_log("Status mask now %02X (val = %02X)\n", dev->status_mask, val);
} }
break; break;
} }
} else { } else {
dev->port = nuked_write_addr(dev->opl, port, val) & 0x01ff; dev->port = nuked_write_addr(dev->opl, port, val) & 0x01ff;
if (! dev->is_opl3) if (!(dev->flags & FLAG_OPL3))
dev->port &= 0x00ff; dev->port &= 0x00ff;
return; return;
@@ -191,7 +184,10 @@ opl_write(opl_t *dev, uint16_t port, uint8_t val)
void void
opl_set_do_cycles(opl_t *dev, int8_t do_cycles) opl_set_do_cycles(opl_t *dev, int8_t do_cycles)
{ {
dev->do_cycles = do_cycles; if (do_cycles)
dev->flags |= FLAG_CYCLES;
else
dev->flags &= ~FLAG_CYCLES;
} }
@@ -200,8 +196,11 @@ opl_init(opl_t *dev, int is_opl3)
{ {
memset(dev, 0x00, sizeof(opl_t)); memset(dev, 0x00, sizeof(opl_t));
dev->is_opl3 = is_opl3; dev->flags = FLAG_CYCLES;
dev->do_cycles = 1; if (is_opl3)
dev->flags |= FLAG_OPL3;
else
dev->status = 0x06;
/* Create a NukedOPL object. */ /* Create a NukedOPL object. */
dev->opl = nuked_init(48000); dev->opl = nuked_init(48000);
@@ -227,7 +226,7 @@ opl2_read(uint16_t port, void *priv)
{ {
opl_t *dev = (opl_t *)priv; opl_t *dev = (opl_t *)priv;
if (dev->do_cycles) if (dev->flags & FLAG_CYCLES)
sub_cycles((int) (isa_timing * 8)); sub_cycles((int) (isa_timing * 8));
opl2_update(dev); opl2_update(dev);
@@ -276,7 +275,7 @@ opl3_read(uint16_t port, void *priv)
{ {
opl_t *dev = (opl_t *)priv; opl_t *dev = (opl_t *)priv;
if (dev->do_cycles) if (dev->flags & FLAG_CYCLES)
sub_cycles((int)(isa_timing * 8)); sub_cycles((int)(isa_timing * 8));
opl3_update(dev); opl3_update(dev);

View File

@@ -31,12 +31,10 @@
* *
* Authors: Fred N. van Kempen, <decwiz@yahoo.com> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
* Alexey Khokholov (Nuke.YKT) * Alexey Khokholov (Nuke.YKT)
* *
* Copyright 2017-2020 Fred N. van Kempen. * Copyright 2017-2020 Fred N. van Kempen.
* Copyright 2016-2020 Miran Grca. * Copyright 2016-2020 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2013-2018 Alexey Khokholov (Nuke.YKT) * Copyright 2013-2018 Alexey Khokholov (Nuke.YKT)
*/ */
#include <stdint.h> #include <stdint.h>