From 871c01f1531eaf55e1b4ec98264751d6238b58cc Mon Sep 17 00:00:00 2001 From: Altheos Date: Sat, 6 Jun 2020 21:35:03 +0200 Subject: [PATCH] Preliminary GUS MAX support --- src/sound/snd_ad1848.c | 39 ++++++++++++++----- src/sound/snd_gus.c | 80 ++++++++++++++++++++++++++++++++++++-- src/win/Makefile.mingw | 12 +++++- src/win/Makefile_ndr.mingw | 12 +++++- 4 files changed, 128 insertions(+), 15 deletions(-) diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index e3ed09981..d2edc6af8 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -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 #include @@ -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; diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index 9fa3bbdc2..19974cf6a 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -14,6 +14,8 @@ #include <86box/device.h> #include <86box/sound.h> #include <86box/midi.h> +#include <86Box/snd_ad1848.h> +#include 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 }, diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index e761fc091..eaea5af4f 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -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, # Fred N. van Kempen, @@ -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 diff --git a/src/win/Makefile_ndr.mingw b/src/win/Makefile_ndr.mingw index 03ae92185..e9a82127d 100644 --- a/src/win/Makefile_ndr.mingw +++ b/src/win/Makefile_ndr.mingw @@ -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, # Fred N. van Kempen, @@ -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