Merge pull request #787 from Altheos/feature/gusmax

Preliminary GUS MAX support
This commit is contained in:
OBattler
2020-06-07 00:14:54 +02:00
committed by GitHub
4 changed files with 128 additions and 15 deletions

View File

@@ -1,6 +1,5 @@
/*PCem v0.8 by Tom Walker
AD1848 CODEC emulation (Windows Sound System compatible)*/
/*
AD1848 / CS4248 / CS4231 CODEC emulation (Windows Sound System compatible)*/
#include <stdio.h>
#include <stdint.h>
@@ -14,6 +13,7 @@
#include <86box/sound.h>
#include <86box/snd_ad1848.h>
#define CS4231 0x80
static int ad1848_vols_6bits[64];
static uint32_t ad1848_vols_5bits_aux_gain[32];
@@ -40,7 +40,11 @@ uint8_t ad1848_read(uint16_t addr, void *p)
break;
case 1:
temp = ad1848->regs[ad1848->index];
break;
if (ad1848->index == 0x0b) {
temp ^= 0x20;
ad1848->regs[ad1848->index] = temp;
}
break;
case 2:
temp = ad1848->status;
break;
@@ -97,6 +101,10 @@ void ad1848_write(uint16_t addr, uint8_t val, void *p)
}
break;
case 11:
break;
case 12:
if (ad1848->type != AD1848_TYPE_DEFAULT)
ad1848->regs[12] = ((ad1848->regs[12] & 0x0f) + (val & 0xf0)) | 0x80;
@@ -105,6 +113,14 @@ void ad1848_write(uint16_t addr, uint8_t val, void *p)
case 14:
ad1848->count = ad1848->regs[15] | (val << 8);
break;
case 24:
if (! (val & 0x70))
ad1848->status &= 0xfe;
break;
case 25:
break;
}
ad1848->regs[ad1848->index] = val;
@@ -197,7 +213,7 @@ static void ad1848_poll(void *p)
if (!(ad1848->status & 0x01))
{
ad1848->status |= 0x01;
if (ad1848->regs[0xa] & 2)
if (ad1848->regs[10] & 2)
picint(1 << ad1848->irq);
}
}
@@ -221,9 +237,9 @@ void ad1848_init(ad1848_t *ad1848, int type)
ad1848->mce = 0x40;
ad1848->regs[0] = ad1848->regs[1] = 0;
ad1848->regs[2] = ad1848->regs[3] = 0x80; /* AZT2316A Line-in */
ad1848->regs[2] = ad1848->regs[3] = 0x80; /* Line-in */
ad1848->regs[4] = ad1848->regs[5] = 0x80;
ad1848->regs[6] = ad1848->regs[7] = 0x80; /* AZT2316A Master? */
ad1848->regs[6] = ad1848->regs[7] = 0x80; /* Left/right Output */
ad1848->regs[8] = 0;
ad1848->regs[9] = 0x08;
ad1848->regs[10] = ad1848->regs[11] = 0;
@@ -236,8 +252,13 @@ void ad1848_init(ad1848_t *ad1848, int type)
if (type == AD1848_TYPE_CS4231)
{
ad1848->regs[0x12] = ad1848->regs[0x13] = 0x80; // AZT2316A CD
ad1848->regs[0x1A] = 0x80; // AZT2316A Mic
ad1848->regs[16] = ad1848->regs[17] = 0;
ad1848->regs[18] = ad1848->regs[19] = 0x88;
ad1848->regs[22] = 0x80;
ad1848->regs[24] = 0;
ad1848->regs[25] = CS4231;
ad1848->regs[26] = 0x80;
ad1848->regs[29] = 0x80;
}
ad1848->out_l = 0;

View File

@@ -14,6 +14,8 @@
#include <86box/device.h>
#include <86box/sound.h>
#include <86box/midi.h>
#include <86Box/snd_ad1848.h>
#include <math.h>
enum
{
@@ -108,6 +110,12 @@ typedef struct gus_t
uint16_t gp1_addr, gp2_addr;
uint8_t usrr;
uint8_t max_ctrl;
#if defined(DEV_BRANCH) && defined(USE_GUSMAX)
ad1848_t ad1848;
#endif
} gus_t;
static int gus_gf1_irqs[8] = {-1, 2, 5, 3, 7, 11, 12, 15};
@@ -182,6 +190,9 @@ void writegus(uint16_t addr, uint8_t val, void *p)
int c, d;
int old;
uint16_t port;
#if defined(DEV_BRANCH) && defined(USE_GUSMAX)
uint16_t csioport;
#endif
if ((addr == 0x388) || (addr == 0x389))
port = addr;
@@ -526,10 +537,16 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
}
else
gus->irq_midi = gus_midi_irqs[(val >> 3) & 7];
#if defined(DEV_BRANCH) && defined(USE_GUSMAX)
ad1848_setirq(&gus->ad1848, gus->irq);
#endif
gus->sb_nmi = val & 0x80;
} else {
gus->dma = gus_dmas[val & 7];
#if defined(DEV_BRANCH) && defined(USE_GUSMAX)
ad1848_setdma(&gus->ad1848, gus->dma);
#endif
}
break;
case 1:
@@ -584,6 +601,25 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
case 0x20f:
gus->reg_ctrl = val;
break;
case 0x306: case 0x706:
if (gus->dma >= 4)
val |= 0x30;
gus->max_ctrl = (val >> 6) & 1;
#if defined(DEV_BRANCH) && defined(USE_GUSMAX)
if (val & 0x40) {
if ((val & 0xF) != ((addr >> 4) & 0xF)) {
csioport = 0x30c | ((addr >> 4) & 0xf);
io_removehandler(csioport, 4,
ad1848_read,NULL,NULL,
ad1848_write,NULL,NULL,&gus->ad1848);
csioport = 0x30c | ((val & 0xf) << 4);
io_sethandler(csioport, 4,
ad1848_read,NULL,NULL,
ad1848_write,NULL,NULL, &gus->ad1848);
}
}
#endif
break;
}
}
@@ -632,7 +668,11 @@ uint8_t readgus(uint16_t addr, void *p)
return val;
case 0x20F:
return 0;
if (gus->max_ctrl)
val = 0x02;
else
val = 0x00;
break;
case 0x302:
return gus->voice;
@@ -719,8 +759,14 @@ uint8_t readgus(uint16_t addr, void *p)
break;
}
break;
case 0x306: case 0x706: /*Revision level*/
return 0xff; /*Pre 3.7 - no mixer*/
case 0x306: case 0x706:
if (gus->max_ctrl)
val = 0x0a; /* GUS MAX */
else
val = 0xff; /*Pre 3.7 - no mixer*/
break;
break;
case 0x307: /*DRAM access*/
val=gus->ram[gus->addr];
gus->addr&=0xFFFFF;
@@ -1031,13 +1077,25 @@ static void gus_get_buffer(int32_t *buffer, int len, void *p)
gus_t *gus = (gus_t *)p;
int c;
#if defined(DEV_BRANCH) && defined(USE_GUSMAX)
if (gus->max_ctrl)
ad1848_update(&gus->ad1848);
#endif
gus_update(gus);
for (c = 0; c < len * 2; c++)
{
#if defined(DEV_BRANCH) && defined(USE_GUSMAX)
if (gus->max_ctrl)
buffer[c] += (int32_t)(gus->ad1848.buffer[c] / 2);
#endif
buffer[c] += (int32_t)gus->buffer[c & 1][c >> 1];
}
#if defined(DEV_BRANCH) && defined(USE_GUSMAX)
if (gus->max_ctrl)
gus->ad1848.pos = 0;
#endif
gus->pos = 0;
}
@@ -1119,6 +1177,15 @@ void *gus_init(const device_t *info)
io_sethandler(0x0100+gus->base, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus);
io_sethandler(0x0506+gus->base, 0x0001, readgus, NULL, NULL, writegus, NULL, NULL, gus);
io_sethandler(0x0388, 0x0002, readgus, NULL, NULL, writegus, NULL, NULL, gus);
#if defined(DEV_BRANCH) && defined(USE_GUSMAX)
ad1848_init(&gus->ad1848, AD1848_TYPE_CS4231);
ad1848_setirq(&gus->ad1848, 5);
ad1848_setdma(&gus->ad1848, 3);
io_sethandler(0x10C+gus->base, 4,
ad1848_read,NULL,NULL, ad1848_write,NULL,NULL, &gus->ad1848);
#endif
timer_add(&gus->samp_timer, gus_poll_wave, gus, 1);
timer_add(&gus->timer_1, gus_poll_timer_1, gus, 1);
timer_add(&gus->timer_2, gus_poll_timer_2, gus, 1);
@@ -1147,6 +1214,11 @@ void gus_speed_changed(void *p)
gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0));
else
gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14]));
#if defined(DEV_BRANCH) && defined(USE_GUSMAX)
if (gus->max_ctrl)
ad1848_speed_changed(&gus->ad1848);
#endif
}
static const device_config_t gus_config[] = {
@@ -1156,7 +1228,7 @@ static const device_config_t gus_config[] = {
{
"Classic", GUS_CLASSIC
},
#if 0
#if defined(DEV_BRANCH) && defined(USE_GUSMAX)
{
"MAX", GUS_MAX
},

View File

@@ -8,7 +8,7 @@
#
# Makefile for Win32 (MinGW32) environment.
#
# Version: @(#)Makefile.mingw 1.0.143 2020/01/25
# Version: @(#)Makefile.mingw 1.0.144 2020/06/06
#
# Authors: Miran Grca, <mgrca8@gmail.com>
# Fred N. van Kempen, <decwiz@yahoo.com>
@@ -86,6 +86,9 @@ ifeq ($(DEV_BUILD), y)
ifndef NO_SIO
NO_SIO := y
endif
ifndef GUSMAX
GUSMAX := y
endif
else
ifndef DEBUG
DEBUG := n
@@ -141,6 +144,9 @@ else
ifndef NO_SIO
NO_SIO := n
endif
ifndef GUSMAX
GUSMAX := n
endif
endif
# Defaults for several build options (possibly defined in a chained file.)
@@ -471,6 +477,10 @@ ifeq ($(NO_SIO), y)
OPTS += -DNO_SIO
endif
ifeq ($(GUSMAX), y)
OPTS += -DUSE_GUSMAX
endif
endif

View File

@@ -8,7 +8,7 @@
#
# Makefile for Win32 (MinGW32) environment.
#
# Version: @(#)Makefile.mingw 1.0.142 2020/01/25
# Version: @(#)Makefile.mingw 1.0.143 2020/06/06
#
# Authors: Miran Grca, <mgrca8@gmail.com>
# Fred N. van Kempen, <decwiz@yahoo.com>
@@ -86,6 +86,9 @@ ifeq ($(DEV_BUILD), y)
ifndef NO_SIO
NO_SIO := y
endif
ifndef GUSMAX
GUSMAX := y
endif
else
ifndef DEBUG
DEBUG := n
@@ -144,6 +147,9 @@ else
ifndef NO_SIO
NO_SIO := n
endif
ifndef GUSMAX
GUSMAX := n
endif
endif
# Defaults for several build options (possibly defined in a chained file.)
@@ -480,6 +486,10 @@ ifeq ($(NO_SIO), y)
OPTS += -DNO_SIO
endif
ifeq ($(GUSMAX), y)
OPTS += -DUSE_GUSMAX
endif
endif