@@ -16,6 +16,36 @@
|
|||||||
#include "midi.h"
|
#include "midi.h"
|
||||||
#include "snd_gus.h"
|
#include "snd_gus.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MIDI_INT_RECEIVE = 0x01,
|
||||||
|
MIDI_INT_TRANSMIT = 0x02,
|
||||||
|
MIDI_INT_MASTER = 0x80
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MIDI_CTRL_TRANSMIT_MASK = 0x60,
|
||||||
|
MIDI_CTRL_TRANSMIT = 0x20,
|
||||||
|
MIDI_CTRL_RECEIVE = 0x80
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
GUS_INT_MIDI_TRANSMIT = 0x01,
|
||||||
|
GUS_INT_MIDI_RECEIVE = 0x02
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
GUS_TIMER_CTRL_AUTO = 0x01
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
GUS_CLASSIC = 0,
|
||||||
|
GUS_MAX = 1,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct gus_t
|
typedef struct gus_t
|
||||||
{
|
{
|
||||||
@@ -52,12 +82,14 @@ typedef struct gus_t
|
|||||||
uint64_t samp_latch;
|
uint64_t samp_latch;
|
||||||
|
|
||||||
uint8_t *ram;
|
uint8_t *ram;
|
||||||
|
uint32_t gus_end_ram;
|
||||||
|
|
||||||
int irqnext;
|
int irqnext;
|
||||||
|
|
||||||
pc_timer_t timer_1, timer_2;
|
pc_timer_t timer_1, timer_2;
|
||||||
|
|
||||||
int irq, dma, irq_midi;
|
int irq, dma, irq_midi;
|
||||||
|
uint16_t base;
|
||||||
int latch_enable;
|
int latch_enable;
|
||||||
|
|
||||||
uint8_t sb_2xa, sb_2xc, sb_2xe;
|
uint8_t sb_2xa, sb_2xc, sb_2xe;
|
||||||
@@ -103,51 +135,26 @@ void pollgusirqs(gus_t *gus)
|
|||||||
gus->irqstatus2=0x60|c;
|
gus->irqstatus2=0x60|c;
|
||||||
if (gus->rampirqs[c]) gus->irqstatus2 |= 0x80;
|
if (gus->rampirqs[c]) gus->irqstatus2 |= 0x80;
|
||||||
gus->irqstatus|=0x20;
|
gus->irqstatus|=0x20;
|
||||||
if (gus->irq != 0)
|
if (gus->irq != 0)
|
||||||
picint(1 << gus->irq);
|
picint(1 << gus->irq);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (gus->rampirqs[c])
|
if (gus->rampirqs[c])
|
||||||
{
|
{
|
||||||
gus->irqstatus2=0xA0|c;
|
gus->irqstatus2=0xA0|c;
|
||||||
gus->irqstatus|=0x40;
|
gus->irqstatus|=0x40;
|
||||||
if (gus->irq != 0)
|
if (gus->irq != 0)
|
||||||
picint(1 << gus->irq);
|
picint(1 << gus->irq);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gus->irqstatus2=0xE0;
|
gus->irqstatus2=0xE0;
|
||||||
if (!gus->irqstatus) {
|
if (!gus->irqstatus) {
|
||||||
if (gus->irq != 0)
|
if (gus->irq != 0)
|
||||||
picintc(1 << gus->irq);
|
picintc(1 << gus->irq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
MIDI_INT_RECEIVE = 0x01,
|
|
||||||
MIDI_INT_TRANSMIT = 0x02,
|
|
||||||
MIDI_INT_MASTER = 0x80
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
MIDI_CTRL_TRANSMIT_MASK = 0x60,
|
|
||||||
MIDI_CTRL_TRANSMIT = 0x20,
|
|
||||||
MIDI_CTRL_RECEIVE = 0x80
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
GUS_INT_MIDI_TRANSMIT = 0x01,
|
|
||||||
GUS_INT_MIDI_RECEIVE = 0x02
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
GUS_TIMER_CTRL_AUTO = 0x01
|
|
||||||
};
|
|
||||||
|
|
||||||
void gus_midi_update_int_status(gus_t *gus)
|
void gus_midi_update_int_status(gus_t *gus)
|
||||||
{
|
{
|
||||||
gus->midi_status &= ~MIDI_INT_MASTER;
|
gus->midi_status &= ~MIDI_INT_MASTER;
|
||||||
@@ -161,8 +168,8 @@ void gus_midi_update_int_status(gus_t *gus)
|
|||||||
|
|
||||||
if ((gus->midi_ctrl & MIDI_CTRL_RECEIVE) && (gus->midi_status & MIDI_INT_RECEIVE))
|
if ((gus->midi_ctrl & MIDI_CTRL_RECEIVE) && (gus->midi_status & MIDI_INT_RECEIVE))
|
||||||
{
|
{
|
||||||
gus->midi_status |= MIDI_INT_MASTER;
|
gus->midi_status |= MIDI_INT_MASTER;
|
||||||
gus->irqstatus |= GUS_INT_MIDI_RECEIVE;
|
gus->irqstatus |= GUS_INT_MIDI_RECEIVE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
gus->irqstatus &= ~GUS_INT_MIDI_RECEIVE;
|
gus->irqstatus &= ~GUS_INT_MIDI_RECEIVE;
|
||||||
@@ -178,42 +185,46 @@ void writegus(uint16_t addr, uint8_t val, void *p)
|
|||||||
gus_t *gus = (gus_t *)p;
|
gus_t *gus = (gus_t *)p;
|
||||||
int c, d;
|
int c, d;
|
||||||
int old;
|
int old;
|
||||||
switch (addr)
|
uint16_t port;
|
||||||
|
|
||||||
|
if ((addr == 0x388) || (addr == 0x389))
|
||||||
|
port = addr;
|
||||||
|
else
|
||||||
|
port = addr & 0xf0f;
|
||||||
|
|
||||||
|
switch (port)
|
||||||
{
|
{
|
||||||
case 0x340: /*MIDI control*/
|
case 0x300: /*MIDI control*/
|
||||||
old = gus->midi_ctrl;
|
old = gus->midi_ctrl;
|
||||||
gus->midi_ctrl = val;
|
gus->midi_ctrl = val;
|
||||||
gus->uart_out = 1;
|
gus->uart_out = 1;
|
||||||
|
|
||||||
if ((val & 3) == 3) { /*Master reset*/
|
if ((val & 3) == 3) { /*Master reset*/
|
||||||
gus->uart_in = 0;
|
gus->uart_in = 0;
|
||||||
gus->midi_status = 0;
|
gus->midi_status = 0;
|
||||||
gus->midi_r = 0;
|
gus->midi_r = 0;
|
||||||
gus->midi_w = 0;
|
gus->midi_w = 0;
|
||||||
} else if ((old & 3) == 3) {
|
} else if ((old & 3) == 3) {
|
||||||
gus->midi_status |= MIDI_INT_TRANSMIT;
|
gus->midi_status |= MIDI_INT_TRANSMIT;
|
||||||
} else if (gus->midi_ctrl & MIDI_CTRL_RECEIVE) {
|
} else if (gus->midi_ctrl & MIDI_CTRL_RECEIVE) {
|
||||||
gus->uart_in = 1;
|
gus->uart_in = 1;
|
||||||
}
|
}
|
||||||
gus_midi_update_int_status(gus);
|
gus_midi_update_int_status(gus);
|
||||||
break;
|
break;
|
||||||
case 0x341: /*MIDI data*/
|
case 0x301: /*MIDI data*/
|
||||||
gus->midi_data = val;
|
gus->midi_data = val;
|
||||||
if (gus->uart_out) {
|
if (gus->uart_out) {
|
||||||
midi_raw_out_byte(val);
|
midi_raw_out_byte(val);
|
||||||
}
|
}
|
||||||
if (gus->latch_enable & 0x20) {
|
if (gus->latch_enable & 0x20) {
|
||||||
gus->midi_status |= MIDI_INT_RECEIVE;
|
gus->midi_status |= MIDI_INT_RECEIVE;
|
||||||
} else
|
} else
|
||||||
gus->midi_status |= MIDI_INT_TRANSMIT;
|
gus->midi_status |= MIDI_INT_TRANSMIT;
|
||||||
break;
|
break;
|
||||||
case 0x342: /*Voice select*/
|
case 0x303: /*Global select*/
|
||||||
gus->voice = val & 31;
|
gus->global=val;
|
||||||
break;
|
break;
|
||||||
case 0x343: /*Global select*/
|
case 0x304: /*Global low*/
|
||||||
gus->global = val;
|
|
||||||
break;
|
|
||||||
case 0x344: /*Global low*/
|
|
||||||
switch (gus->global)
|
switch (gus->global)
|
||||||
{
|
{
|
||||||
case 0: /*Voice control*/
|
case 0: /*Voice control*/
|
||||||
@@ -265,7 +276,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8);
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x345: /*Global high*/
|
case 0x305: /*Global high*/
|
||||||
switch (gus->global)
|
switch (gus->global)
|
||||||
{
|
{
|
||||||
case 0: /*Voice control*/
|
case 0: /*Voice control*/
|
||||||
@@ -451,11 +462,12 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x347: /*DRAM access*/
|
case 0x307: /*DRAM access*/
|
||||||
gus->ram[gus->addr]=val;
|
|
||||||
gus->addr&=0xFFFFF;
|
gus->addr&=0xFFFFF;
|
||||||
|
if (gus->addr < gus->gus_end_ram)
|
||||||
|
gus->ram[gus->addr]=val;
|
||||||
break;
|
break;
|
||||||
case 0x248: case 0x388:
|
case 0x208: case 0x388:
|
||||||
gus->adcommand = val;
|
gus->adcommand = val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -495,11 +507,11 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x240:
|
case 0x200:
|
||||||
gus->latch_enable = val;
|
gus->latch_enable = val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x24b:
|
case 0x20b:
|
||||||
switch (gus->reg_ctrl & 0x07)
|
switch (gus->reg_ctrl & 0x07)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@@ -586,19 +598,19 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x246:
|
case 0x206:
|
||||||
if (gus->sb_ctrl & 0x20) {
|
if (gus->sb_ctrl & 0x20) {
|
||||||
gus->ad_status |= 0x08;
|
gus->ad_status |= 0x08;
|
||||||
if (gus->sb_nmi)
|
if (gus->sb_nmi)
|
||||||
nmi = 1;
|
nmi = 1;
|
||||||
else if (gus->irq != 0)
|
else if (gus->irq != 0)
|
||||||
picint(1 << gus->irq);
|
picint(1 << gus->irq);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x24a:
|
case 0x20a:
|
||||||
gus->sb_2xa = val;
|
gus->sb_2xa = val;
|
||||||
break;
|
break;
|
||||||
case 0x24c:
|
case 0x20c:
|
||||||
gus->ad_status |= 0x10;
|
gus->ad_status |= 0x10;
|
||||||
if (gus->sb_ctrl & 0x20)
|
if (gus->sb_ctrl & 0x20)
|
||||||
{
|
{
|
||||||
@@ -607,29 +619,37 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
|||||||
else if (gus->irq != 0)
|
else if (gus->irq != 0)
|
||||||
picint(1 << gus->irq);
|
picint(1 << gus->irq);
|
||||||
}
|
}
|
||||||
case 0x24d:
|
case 0x20d:
|
||||||
gus->sb_2xc = val;
|
gus->sb_2xc = val;
|
||||||
break;
|
break;
|
||||||
case 0x24e:
|
case 0x20e:
|
||||||
gus->sb_2xe = val;
|
gus->sb_2xe = val;
|
||||||
break;
|
break;
|
||||||
case 0x24f:
|
case 0x20f:
|
||||||
gus->reg_ctrl = val;
|
gus->reg_ctrl = val;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t readgus(uint16_t addr, void *p)
|
uint8_t readgus(uint16_t addr, void *p)
|
||||||
{
|
{
|
||||||
gus_t *gus = (gus_t *)p;
|
gus_t *gus = (gus_t *)p;
|
||||||
uint8_t val = 0xff;
|
uint8_t val = 0xff;
|
||||||
switch (addr)
|
uint16_t port;
|
||||||
|
|
||||||
|
if ((addr == 0x388) || (addr == 0x389))
|
||||||
|
port = addr;
|
||||||
|
else
|
||||||
|
port = addr & 0xf0f;
|
||||||
|
|
||||||
|
switch (port)
|
||||||
{
|
{
|
||||||
case 0x340: /*MIDI status*/
|
case 0x300: /*MIDI status*/
|
||||||
val = gus->midi_status;
|
val = gus->midi_status;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x341: /*MIDI data*/
|
case 0x301: /*MIDI data*/
|
||||||
val = 0;
|
val = 0;
|
||||||
if (gus->uart_in) {
|
if (gus->uart_in) {
|
||||||
if ((gus->midi_data == 0xaa) && (gus->midi_ctrl & MIDI_CTRL_RECEIVE)) /*Handle master reset*/
|
if ((gus->midi_data == 0xaa) && (gus->midi_ctrl & MIDI_CTRL_RECEIVE)) /*Handle master reset*/
|
||||||
@@ -646,29 +666,29 @@ uint8_t readgus(uint16_t addr, void *p)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x240:
|
case 0x200:
|
||||||
val = 0xff;
|
val = 0xff;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x246: /*IRQ status*/
|
case 0x206: /*IRQ status*/
|
||||||
val = gus->irqstatus & ~0x10;
|
val = gus->irqstatus & ~0x10;
|
||||||
if (gus->ad_status & 0x19)
|
if (gus->ad_status & 0x19)
|
||||||
val |= 0x10;
|
val |= 0x10;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x24F:
|
case 0x20F:
|
||||||
val = 0;
|
val = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x342:
|
case 0x302:
|
||||||
val = gus->voice;
|
val = gus->voice;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x343:
|
case 0x303:
|
||||||
val = gus->global;
|
val = gus->global;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x344: /*Global low*/
|
case 0x304: /*Global low*/
|
||||||
switch (gus->global)
|
switch (gus->global)
|
||||||
{
|
{
|
||||||
case 0x82: /*Start addr high*/
|
case 0x82: /*Start addr high*/
|
||||||
@@ -698,7 +718,7 @@ uint8_t readgus(uint16_t addr, void *p)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x345: /*Global high*/
|
case 0x305: /*Global high*/
|
||||||
switch (gus->global)
|
switch (gus->global)
|
||||||
{
|
{
|
||||||
case 0x80: /*Voice control*/
|
case 0x80: /*Voice control*/
|
||||||
@@ -747,16 +767,20 @@ uint8_t readgus(uint16_t addr, void *p)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x346: return 0xff;
|
case 0x306: case 0x706: /*Revision level*/
|
||||||
case 0x347: /*DRAM access*/
|
val = 0xff;
|
||||||
|
break;
|
||||||
|
case 0x307: /*DRAM access*/
|
||||||
val=gus->ram[gus->addr];
|
val=gus->ram[gus->addr];
|
||||||
gus->addr&=0xFFFFF;
|
gus->addr&=0xFFFFF;
|
||||||
return val;
|
if (gus->addr < gus->gus_end_ram)
|
||||||
case 0x349: return 0;
|
val = gus->ram[gus->addr];
|
||||||
case 0x746: /*Revision level*/
|
else
|
||||||
return 0xff; /*Pre 3.7 - no mixer*/
|
val = 0;
|
||||||
|
break;
|
||||||
|
case 0x309: return 0;
|
||||||
|
|
||||||
case 0x24b:
|
case 0x20b:
|
||||||
switch (gus->reg_ctrl & 0x07)
|
switch (gus->reg_ctrl & 0x07)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
@@ -774,15 +798,15 @@ uint8_t readgus(uint16_t addr, void *p)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x24c:
|
case 0x20c:
|
||||||
val = gus->sb_2xc;
|
val = gus->sb_2xc;
|
||||||
if (gus->reg_ctrl & 0x20)
|
if (gus->reg_ctrl & 0x20)
|
||||||
gus->sb_2xc &= 0x80;
|
gus->sb_2xc &= 0x80;
|
||||||
break;
|
break;
|
||||||
case 0x24e:
|
case 0x20e:
|
||||||
return gus->sb_2xe;
|
return gus->sb_2xe;
|
||||||
|
|
||||||
case 0x248: case 0x388:
|
case 0x208: case 0x388:
|
||||||
if (gus->tctrl & GUS_TIMER_CTRL_AUTO)
|
if (gus->tctrl & GUS_TIMER_CTRL_AUTO)
|
||||||
val = gus->sb_2xa;
|
val = gus->sb_2xa;
|
||||||
else
|
else
|
||||||
@@ -793,14 +817,14 @@ uint8_t readgus(uint16_t addr, void *p)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x249:
|
case 0x209:
|
||||||
gus->ad_status &= ~0x01;
|
gus->ad_status &= ~0x01;
|
||||||
nmi = 0;
|
nmi = 0;
|
||||||
case 0x389:
|
case 0x389:
|
||||||
val = gus->ad_data;
|
val = gus->ad_data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x24A:
|
case 0x20A:
|
||||||
val = gus->adcommand;
|
val = gus->adcommand;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -822,9 +846,9 @@ void gus_poll_timer_1(void *p)
|
|||||||
gus->ad_status |= 0x40;
|
gus->ad_status |= 0x40;
|
||||||
if (gus->tctrl&4)
|
if (gus->tctrl&4)
|
||||||
{
|
{
|
||||||
if (gus->irq != 0)
|
if (gus->irq != 0)
|
||||||
picint(1 << gus->irq);
|
picint(1 << gus->irq);
|
||||||
gus->ad_status |= 0x04;
|
gus->ad_status |= 0x04;
|
||||||
gus->irqstatus |= 0x04;
|
gus->irqstatus |= 0x04;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -833,8 +857,8 @@ void gus_poll_timer_1(void *p)
|
|||||||
{
|
{
|
||||||
gus->irqnext=0;
|
gus->irqnext=0;
|
||||||
gus->irqstatus|=0x80;
|
gus->irqstatus|=0x80;
|
||||||
if (gus->irq != 0)
|
if (gus->irq != 0)
|
||||||
picint(1 << gus->irq);
|
picint(1 << gus->irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
gus_midi_update_int_status(gus);
|
gus_midi_update_int_status(gus);
|
||||||
@@ -854,8 +878,8 @@ void gus_poll_timer_2(void *p)
|
|||||||
gus->ad_status |= 0x20;
|
gus->ad_status |= 0x20;
|
||||||
if (gus->tctrl&8)
|
if (gus->tctrl&8)
|
||||||
{
|
{
|
||||||
if (gus->irq != 0)
|
if (gus->irq != 0)
|
||||||
picint(1 << gus->irq);
|
picint(1 << gus->irq);
|
||||||
gus->ad_status |= 0x02;
|
gus->ad_status |= 0x02;
|
||||||
gus->irqstatus |= 0x08;
|
gus->irqstatus |= 0x08;
|
||||||
}
|
}
|
||||||
@@ -866,7 +890,7 @@ void gus_poll_timer_2(void *p)
|
|||||||
gus->irqnext=0;
|
gus->irqnext=0;
|
||||||
gus->irqstatus|=0x80;
|
gus->irqstatus|=0x80;
|
||||||
if (gus->irq != 0)
|
if (gus->irq != 0)
|
||||||
picint(1 << gus->irq);
|
picint(1 << gus->irq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1109,11 +1133,13 @@ void *gus_init(const device_t *info)
|
|||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
double out = 1.0;
|
double out = 1.0;
|
||||||
|
uint8_t gus_ram = device_get_config_int("gus_ram");
|
||||||
gus_t *gus = malloc(sizeof(gus_t));
|
gus_t *gus = malloc(sizeof(gus_t));
|
||||||
memset(gus, 0, sizeof(gus_t));
|
memset(gus, 0, sizeof(gus_t));
|
||||||
|
|
||||||
gus->ram = malloc(1 << 20);
|
gus->gus_end_ram = 1 << (18 + gus_ram);
|
||||||
memset(gus->ram, 0, 1 << 20);
|
gus->ram = (uint8_t *)malloc(gus->gus_end_ram);
|
||||||
|
memset(gus->ram, 0x00, (gus->gus_end_ram));
|
||||||
|
|
||||||
for (c=0;c<32;c++)
|
for (c=0;c<32;c++)
|
||||||
{
|
{
|
||||||
@@ -1132,12 +1158,14 @@ void *gus_init(const device_t *info)
|
|||||||
gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0));
|
gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0));
|
||||||
|
|
||||||
gus->t1l = gus->t2l = 0xff;
|
gus->t1l = gus->t2l = 0xff;
|
||||||
|
|
||||||
gus->uart_out = 1;
|
gus->uart_out = 1;
|
||||||
|
|
||||||
io_sethandler(0x0240, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus);
|
gus->base = device_get_config_hex16("base");
|
||||||
io_sethandler(0x0340, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus);
|
|
||||||
io_sethandler(0x0746, 0x0001, readgus, NULL, NULL, writegus, NULL, NULL, gus);
|
io_sethandler(gus->base, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus);
|
||||||
|
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);
|
io_sethandler(0x0388, 0x0002, readgus, NULL, NULL, writegus, NULL, NULL, gus);
|
||||||
timer_add(&gus->samp_timer, gus_poll_wave, gus, 1);
|
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_1, gus_poll_timer_1, gus, 1);
|
||||||
@@ -1145,9 +1173,9 @@ void *gus_init(const device_t *info)
|
|||||||
|
|
||||||
sound_add_handler(gus_get_buffer, gus);
|
sound_add_handler(gus_get_buffer, gus);
|
||||||
|
|
||||||
input_msg = gus_input_msg;
|
input_msg = gus_input_msg;
|
||||||
input_sysex = gus_input_sysex;
|
input_sysex = gus_input_sysex;
|
||||||
midi_in_p = gus;
|
midi_in_p = gus;
|
||||||
|
|
||||||
return gus;
|
return gus;
|
||||||
}
|
}
|
||||||
@@ -1170,11 +1198,76 @@ void gus_speed_changed(void *p)
|
|||||||
gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14]));
|
gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const device_config_t gus_config[] = {
|
||||||
|
{
|
||||||
|
"type", "GUS type", CONFIG_SELECTION, "", 0,
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"Classic", GUS_CLASSIC
|
||||||
|
},
|
||||||
|
#if 0
|
||||||
|
{
|
||||||
|
"MAX", GUS_MAX
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
NULL
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"base", "Address", CONFIG_HEX16, "", 0x220,
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"210H", 0x210
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"220H", 0x220
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"230H", 0x230
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"240H", 0x240
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"250H", 0x250
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"260H", 0x260
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"gus_ram", "Onboard RAM", CONFIG_SELECTION, "", 0,
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"256 KB", 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"512 KB", 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"1 MB", 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
NULL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"", "", -1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const device_t gus_device =
|
const device_t gus_device =
|
||||||
{
|
{
|
||||||
"Gravis UltraSound",
|
"Gravis UltraSound",
|
||||||
0, 0,
|
DEVICE_ISA,
|
||||||
gus_init, gus_close, NULL, NULL,
|
0,
|
||||||
gus_speed_changed, NULL,
|
gus_init, gus_close, NULL,
|
||||||
NULL
|
NULL,
|
||||||
|
gus_speed_changed,
|
||||||
|
NULL,
|
||||||
|
gus_config
|
||||||
};
|
};
|
||||||
|
@@ -366,7 +366,7 @@ BEGIN
|
|||||||
PUSHBUTTON "Joystick 4...",IDC_JOY4,209,44,50,14
|
PUSHBUTTON "Joystick 4...",IDC_JOY4,209,44,50,14
|
||||||
END
|
END
|
||||||
|
|
||||||
DLG_CFG_SOUND DIALOG DISCARDABLE 97, 0, 267, 116
|
DLG_CFG_SOUND DIALOG DISCARDABLE 97, 0, 267, 199
|
||||||
STYLE DS_CONTROL | WS_CHILD
|
STYLE DS_CONTROL | WS_CHILD
|
||||||
FONT 9, "Segoe UI"
|
FONT 9, "Segoe UI"
|
||||||
BEGIN
|
BEGIN
|
||||||
@@ -395,9 +395,11 @@ BEGIN
|
|||||||
BS_AUTOCHECKBOX | WS_TABSTOP,147,83,94,10
|
BS_AUTOCHECKBOX | WS_TABSTOP,147,83,94,10
|
||||||
|
|
||||||
CONTROL "Gravis Ultrasound",IDC_CHECK_GUS,"Button",
|
CONTROL "Gravis Ultrasound",IDC_CHECK_GUS,"Button",
|
||||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,101,94,10
|
BS_AUTOCHECKBOX | WS_TABSTOP,7,99,94,10
|
||||||
|
PUSHBUTTON "Configure",IDC_CONFIGURE_GUS,214,99,46,12
|
||||||
|
|
||||||
CONTROL "Use FLOAT32 sound",IDC_CHECK_FLOAT,"Button",
|
CONTROL "Use FLOAT32 sound",IDC_CHECK_FLOAT,"Button",
|
||||||
BS_AUTOCHECKBOX | WS_TABSTOP,147,101,94,10
|
BS_AUTOCHECKBOX | WS_TABSTOP,7,115,94,10
|
||||||
END
|
END
|
||||||
|
|
||||||
DLG_CFG_NETWORK DIALOG DISCARDABLE 97, 0, 267, 63
|
DLG_CFG_NETWORK DIALOG DISCARDABLE 97, 0, 267, 63
|
||||||
|
@@ -149,8 +149,8 @@
|
|||||||
#define IDC_CHECK_MPU401 1076
|
#define IDC_CHECK_MPU401 1076
|
||||||
#define IDC_CONFIGURE_MPU401 1077
|
#define IDC_CONFIGURE_MPU401 1077
|
||||||
#define IDC_CHECK_FLOAT 1078
|
#define IDC_CHECK_FLOAT 1078
|
||||||
#define IDC_CHECK_GUSMAX 1079
|
#define IDC_CONFIGURE_GUS 1079
|
||||||
#define IDC_COMBO_MIDI_IN 1080
|
#define IDC_COMBO_MIDI_IN 1080
|
||||||
|
|
||||||
#define IDC_COMBO_NET_TYPE 1090 /* network config */
|
#define IDC_COMBO_NET_TYPE 1090 /* network config */
|
||||||
#define IDC_COMBO_PCAP 1091
|
#define IDC_COMBO_PCAP 1091
|
||||||
|
@@ -56,6 +56,7 @@
|
|||||||
#include "../sound/sound.h"
|
#include "../sound/sound.h"
|
||||||
#include "../sound/midi.h"
|
#include "../sound/midi.h"
|
||||||
#include "../sound/snd_mpu401.h"
|
#include "../sound/snd_mpu401.h"
|
||||||
|
#include "../sound/snd_gus.h"
|
||||||
#include "../video/video.h"
|
#include "../video/video.h"
|
||||||
#include "../video/vid_voodoo.h"
|
#include "../video/vid_voodoo.h"
|
||||||
#include "../plat.h"
|
#include "../plat.h"
|
||||||
@@ -1117,7 +1118,6 @@ mpu401_standalone_allow(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(__amd64__) || defined(__aarch64__)
|
#if defined(__amd64__) || defined(__aarch64__)
|
||||||
static LRESULT CALLBACK
|
static LRESULT CALLBACK
|
||||||
#else
|
#else
|
||||||
@@ -1245,7 +1245,10 @@ win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
|
|
||||||
h=GetDlgItem(hdlg, IDC_CHECK_GUS);
|
h=GetDlgItem(hdlg, IDC_CHECK_GUS);
|
||||||
SendMessage(h, BM_SETCHECK, temp_GUS, 0);
|
SendMessage(h, BM_SETCHECK, temp_GUS, 0);
|
||||||
|
|
||||||
|
h = GetDlgItem(hdlg, IDC_CONFIGURE_GUS);
|
||||||
|
EnableWindow(h, (temp_GUS) ? TRUE : FALSE);
|
||||||
|
|
||||||
h=GetDlgItem(hdlg, IDC_CHECK_SSI);
|
h=GetDlgItem(hdlg, IDC_CHECK_SSI);
|
||||||
SendMessage(h, BM_SETCHECK, temp_SSI2001, 0);
|
SendMessage(h, BM_SETCHECK, temp_SSI2001, 0);
|
||||||
|
|
||||||
@@ -1345,6 +1348,18 @@ win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
temp_deviceconfig |= deviceconfig_open(hdlg, (machines[temp_machine].flags & MACHINE_MCA) ?
|
temp_deviceconfig |= deviceconfig_open(hdlg, (machines[temp_machine].flags & MACHINE_MCA) ?
|
||||||
(void *)&mpu401_mca_device : (void *)&mpu401_device);
|
(void *)&mpu401_mca_device : (void *)&mpu401_device);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IDC_CHECK_GUS:
|
||||||
|
h = GetDlgItem(hdlg, IDC_CHECK_GUS);
|
||||||
|
temp_GUS = SendMessage(h, BM_GETCHECK, 0, 0);
|
||||||
|
|
||||||
|
h = GetDlgItem(hdlg, IDC_CONFIGURE_GUS);
|
||||||
|
EnableWindow(h, temp_GUS ? TRUE : FALSE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IDC_CONFIGURE_GUS:
|
||||||
|
temp_deviceconfig |= deviceconfig_open(hdlg, (void *)&gus_device);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user