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

View File

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

View File

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