Merge pull request #787 from Altheos/feature/gusmax
Preliminary GUS MAX support
This commit is contained in:
@@ -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;
|
||||
|
@@ -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
|
||||
},
|
||||
|
@@ -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
|
||||
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user