Fixed gcc 10.1.0 warning "clearing an object of non-trivial type". Now moving
the buffer objects and data members to different structures and use memset() for data only.
This commit is contained in:
parent
40726e4c7c
commit
3db989b9a8
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2018 The Bochs Project
|
||||
// Copyright (C) 2001-2020 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -183,8 +183,10 @@ void CDECL libsb16_LTX_plugin_fini(void)
|
||||
|
||||
// some shortcuts to save typing
|
||||
#define LOGFILE BX_SB16_THIS logfile
|
||||
#define MPU BX_SB16_THIS mpu401
|
||||
#define DSP BX_SB16_THIS dsp
|
||||
#define MPU BX_SB16_THIS mpu401.d
|
||||
#define MPU_B BX_SB16_THIS mpu401.b
|
||||
#define DSP BX_SB16_THIS dsp.d
|
||||
#define DSP_B BX_SB16_THIS dsp.b
|
||||
#define MIXER BX_SB16_THIS mixer
|
||||
#define EMUL BX_SB16_THIS emuldata
|
||||
#define OPL BX_SB16_THIS opl
|
||||
@ -203,13 +205,13 @@ void CDECL libsb16_LTX_plugin_fini(void)
|
||||
bx_sb16_c::bx_sb16_c(void)
|
||||
{
|
||||
put("SB16");
|
||||
memset(&mpu401, 0, sizeof(mpu401));
|
||||
memset(&dsp, 0, sizeof(dsp));
|
||||
memset(&mpu401.d, 0, sizeof(mpu401.d));
|
||||
memset(&dsp.d, 0, sizeof(dsp.d));
|
||||
memset(&opl, 0, sizeof(opl));
|
||||
currentdma8 = 0;
|
||||
currentdma16 = 0;
|
||||
mpu401.timer_handle = BX_NULL_TIMER_HANDLE;
|
||||
dsp.timer_handle = BX_NULL_TIMER_HANDLE;
|
||||
mpu401.d.timer_handle = BX_NULL_TIMER_HANDLE;
|
||||
dsp.d.timer_handle = BX_NULL_TIMER_HANDLE;
|
||||
opl.timer_handle = BX_NULL_TIMER_HANDLE;
|
||||
waveout[0] = NULL;
|
||||
waveout[1] = NULL;
|
||||
@ -314,14 +316,14 @@ void bx_sb16_c::init(void)
|
||||
|
||||
// allocate the FIFO buffers - except for the MPUMIDICMD buffer
|
||||
// these sizes are generous, 16 or 8 would probably be sufficient
|
||||
MPU.datain.init((int) 64); // the input
|
||||
MPU.dataout.init((int) 64); // and output
|
||||
MPU.cmd.init((int) 64); // and command buffers
|
||||
MPU.midicmd.init((int) 256); // and the midi command buffer (note- large SYSEX'es have to fit!)
|
||||
DSP.datain.init((int) 64); // the DSP input
|
||||
DSP.dataout.init((int) 64); // and output buffers
|
||||
EMUL.datain.init((int) 64); // the emulator ports
|
||||
EMUL.dataout.init((int) 64); // for changing emulator settings
|
||||
MPU_B.datain.init((int) 64); // the MPU input
|
||||
MPU_B.dataout.init((int) 64); // and output
|
||||
MPU_B.cmd.init((int) 64); // and command buffers
|
||||
MPU_B.midicmd.init((int) 256); // and the midi command buffer (note- large SYSEX'es have to fit!)
|
||||
DSP_B.datain.init((int) 64); // the DSP input
|
||||
DSP_B.dataout.init((int) 64); // and output buffers
|
||||
EMUL.datain.init((int) 64); // the emulator ports
|
||||
EMUL.dataout.init((int) 64); // for changing emulator settings
|
||||
|
||||
// reset all parts of the hardware by
|
||||
// triggering their reset functions
|
||||
@ -406,7 +408,7 @@ void bx_sb16_c::init(void)
|
||||
|
||||
if (DSP.timer_handle == BX_NULL_TIMER_HANDLE) {
|
||||
DSP.timer_handle = DEV_register_timer
|
||||
(BX_SB16_THISP, dsp_dmatimer, 1, 1, 0, "sb16.dsp");
|
||||
(BX_SB16_THISP, dsp_dmatimer_handler, 1, 1, 0, "sb16.dsp");
|
||||
// dma timer: inactive, continuous, frequency variable
|
||||
}
|
||||
|
||||
@ -583,24 +585,27 @@ void bx_sb16_c::runtime_config(void)
|
||||
// the timer functions
|
||||
void bx_sb16_c::mpu_timer (void *this_ptr)
|
||||
{
|
||||
((bx_sb16_c *) this_ptr)->mpu401.current_timer++;
|
||||
((bx_sb16_c *) this_ptr)->mpu401.d.current_timer++;
|
||||
}
|
||||
|
||||
void bx_sb16_c::dsp_dmatimer(void *this_ptr)
|
||||
void bx_sb16_c::dsp_dmatimer_handler(void *this_ptr)
|
||||
{
|
||||
bx_sb16_c *This = (bx_sb16_c *) this_ptr;
|
||||
((bx_sb16_c *) this_ptr)->dsp_dmatimer();
|
||||
}
|
||||
|
||||
void bx_sb16_c::dsp_dmatimer(void)
|
||||
{
|
||||
// raise the DRQ line. It is then lowered by the dma read / write functions
|
||||
// when the next byte has been sent / received.
|
||||
// However, don't do this if the next byte/word will fill up the
|
||||
// output buffer and the output functions are not ready yet
|
||||
// or if buffer is empty in input mode.
|
||||
|
||||
if (!This->dsp.nondma_mode) {
|
||||
if ((This->dsp.dma.chunkindex + 1 < BX_SOUNDLOW_WAVEPACKETSIZE) &&
|
||||
(This->dsp.dma.count > 0)) {
|
||||
if (((This->dsp.dma.output == 0) && (This->dsp.dma.chunkcount > 0)) ||
|
||||
(This->dsp.dma.output == 1)) {
|
||||
if (!DSP.nondma_mode) {
|
||||
if ((DSP.dma.chunkindex + 1 < BX_SOUNDLOW_WAVEPACKETSIZE) &&
|
||||
(DSP.dma.count > 0)) {
|
||||
if (((DSP.dma.output == 0) && (DSP.dma.chunkcount > 0)) ||
|
||||
(DSP.dma.output == 1)) {
|
||||
if ((DSP.dma.param.bits == 8) || (BX_SB16_DMAH == 0)) {
|
||||
DEV_dma_set_drq(BX_SB16_DMAL, 1);
|
||||
} else {
|
||||
@ -610,9 +615,9 @@ void bx_sb16_c::dsp_dmatimer(void *this_ptr)
|
||||
}
|
||||
} else {
|
||||
dsp_getsamplebyte(0);
|
||||
dsp_getsamplebyte(This->dsp.samplebyte);
|
||||
dsp_getsamplebyte(DSP.samplebyte);
|
||||
dsp_getsamplebyte(0);
|
||||
dsp_getsamplebyte(This->dsp.samplebyte);
|
||||
dsp_getsamplebyte(DSP.samplebyte);
|
||||
}
|
||||
}
|
||||
|
||||
@ -684,10 +689,10 @@ void bx_sb16_c::dsp_reset(Bit32u value)
|
||||
DSP.dma.highspeed = 0;
|
||||
DSP.dma.chunkindex = 0;
|
||||
|
||||
DSP.dataout.reset(); // clear the buffers
|
||||
DSP.datain.reset();
|
||||
DSP_B.dataout.reset(); // clear the buffers
|
||||
DSP_B.datain.reset();
|
||||
|
||||
DSP.dataout.put(0xaa); // acknowledge the reset
|
||||
DSP_B.dataout.put(0xaa); // acknowledge the reset
|
||||
}
|
||||
else
|
||||
DSP.resetport = value;
|
||||
@ -704,8 +709,8 @@ Bit32u bx_sb16_c::dsp_dataread()
|
||||
else
|
||||
{
|
||||
// default behaviour: if none available, return last byte again
|
||||
// if (DSP.dataout.empty() == 0)
|
||||
DSP.dataout.get(&value);
|
||||
// if (DSP_B.dataout.empty() == 0)
|
||||
DSP_B.dataout.get(&value);
|
||||
}
|
||||
|
||||
writelog(WAVELOG(4), "DSP Data port read, result = %x", value);
|
||||
@ -736,12 +741,12 @@ void bx_sb16_c::dsp_datawrite(Bit32u value)
|
||||
return;
|
||||
}
|
||||
|
||||
if (DSP.datain.hascommand() == 1) // already a command pending, add to argument list
|
||||
if (DSP_B.datain.hascommand() == 1) // already a command pending, add to argument list
|
||||
{
|
||||
if (DSP.datain.put(value) == 0)
|
||||
if (DSP_B.datain.put(value) == 0)
|
||||
{
|
||||
writelog(WAVELOG(3), "DSP command buffer overflow for command %02x",
|
||||
DSP.datain.currentcommand());
|
||||
DSP_B.datain.currentcommand());
|
||||
}
|
||||
}
|
||||
else // no command pending, set one up
|
||||
@ -813,15 +818,15 @@ void bx_sb16_c::dsp_datawrite(Bit32u value)
|
||||
bytesneeded = 3;
|
||||
break;
|
||||
}
|
||||
DSP.datain.newcommand(value, bytesneeded);
|
||||
DSP_B.datain.newcommand(value, bytesneeded);
|
||||
}
|
||||
|
||||
if (DSP.datain.commanddone() == 1) // command is complete, process it
|
||||
if (DSP_B.datain.commanddone() == 1) // command is complete, process it
|
||||
{
|
||||
writelog(WAVELOG(4), "DSP command %x with %d arg bytes",
|
||||
DSP.datain.currentcommand(), DSP.datain.bytes());
|
||||
DSP_B.datain.currentcommand(), DSP_B.datain.bytes());
|
||||
|
||||
switch (DSP.datain.currentcommand())
|
||||
switch (DSP_B.datain.currentcommand())
|
||||
{
|
||||
// DSP commands - comments are the parameters for
|
||||
// this command, and/or the output
|
||||
@ -829,23 +834,23 @@ void bx_sb16_c::dsp_datawrite(Bit32u value)
|
||||
// ASP commands (Advanced Signal Processor)
|
||||
// undocumented (?), just from looking what an SB16 does
|
||||
case 0x04:
|
||||
DSP.datain.get(&value8);
|
||||
DSP_B.datain.get(&value8);
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
DSP.datain.get(&value8);
|
||||
DSP.datain.get(&value8);
|
||||
DSP_B.datain.get(&value8);
|
||||
DSP_B.datain.get(&value8);
|
||||
break;
|
||||
|
||||
case 0x0e:
|
||||
DSP.datain.get(&index);
|
||||
DSP.datain.get(&value8);
|
||||
DSP_B.datain.get(&index);
|
||||
DSP_B.datain.get(&value8);
|
||||
BX_SB16_THIS csp_reg[index] = value;
|
||||
break;
|
||||
|
||||
case 0x0f:
|
||||
DSP.datain.get(&index);
|
||||
DSP.dataout.put(BX_SB16_THIS csp_reg[index]);
|
||||
DSP_B.datain.get(&index);
|
||||
DSP_B.dataout.put(BX_SB16_THIS csp_reg[index]);
|
||||
break;
|
||||
|
||||
// direct mode DAC
|
||||
@ -862,28 +867,28 @@ void bx_sb16_c::dsp_datawrite(Bit32u value)
|
||||
DSP.nondma_mode = 1;
|
||||
DSP.nondma_count = 0;
|
||||
}
|
||||
DSP.datain.get(&DSP.samplebyte);
|
||||
DSP_B.datain.get(&DSP.samplebyte);
|
||||
DSP.nondma_count++;
|
||||
break;
|
||||
|
||||
// uncomp'd, normal DAC DMA
|
||||
case 0x14:
|
||||
// 1,2: lo(length) hi(length)
|
||||
DSP.datain.getw(&length);
|
||||
DSP_B.datain.getw(&length);
|
||||
dsp_dma(0xc0, 0x00, length, 0);
|
||||
break;
|
||||
|
||||
// 2-bit comp'd, normal DAC DMA, no ref byte
|
||||
case 0x16:
|
||||
// 1,2: lo(length) hi(length)
|
||||
DSP.datain.getw(&length);
|
||||
DSP_B.datain.getw(&length);
|
||||
dsp_dma(0xc0, 0x00, length, 2);
|
||||
break;
|
||||
|
||||
// 2-bit comp'd, normal DAC DMA, 1 ref byte
|
||||
case 0x17:
|
||||
// 1,2: lo(length) hi(length)
|
||||
DSP.datain.getw(&length);
|
||||
DSP_B.datain.getw(&length);
|
||||
dsp_dma(0xc0, 0x00, length, 2|8);
|
||||
break;
|
||||
|
||||
@ -902,13 +907,13 @@ void bx_sb16_c::dsp_datawrite(Bit32u value)
|
||||
// direct mode ADC
|
||||
case 0x20:
|
||||
// o1: 8bit sample
|
||||
DSP.dataout.put(0x80); // put a silence, for now.
|
||||
DSP_B.dataout.put(0x80); // put a silence, for now.
|
||||
break;
|
||||
|
||||
// uncomp'd, normal ADC DMA
|
||||
case 0x24:
|
||||
// 1,2: lo(length) hi(length)
|
||||
DSP.datain.getw(&length);
|
||||
DSP_B.datain.getw(&length);
|
||||
dsp_dma(0xc8, 0x00, length, 0);
|
||||
break;
|
||||
|
||||
@ -943,7 +948,7 @@ void bx_sb16_c::dsp_datawrite(Bit32u value)
|
||||
|
||||
// MIDI output
|
||||
case 0x38:
|
||||
DSP.datain.get(&value8);
|
||||
DSP_B.datain.get(&value8);
|
||||
// route to mpu401 part
|
||||
mpu_datawrite(value8);
|
||||
break;
|
||||
@ -951,7 +956,7 @@ void bx_sb16_c::dsp_datawrite(Bit32u value)
|
||||
// set time constant
|
||||
case 0x40:
|
||||
// 1: timeconstant
|
||||
DSP.datain.get(&value8);
|
||||
DSP_B.datain.get(&value8);
|
||||
DSP.dma.timeconstant = value8 << 8;
|
||||
DSP.dma.param.samplerate = (Bit32u) 256000000L / ((Bit32u) 65536L - (Bit32u) DSP.dma.timeconstant);
|
||||
break;
|
||||
@ -963,41 +968,41 @@ void bx_sb16_c::dsp_datawrite(Bit32u value)
|
||||
// set samplerate for output
|
||||
case 0x42:
|
||||
// 1,2: hi(frq) lo(frq)
|
||||
DSP.datain.getw1(&(DSP.dma.param.samplerate));
|
||||
DSP_B.datain.getw1(&(DSP.dma.param.samplerate));
|
||||
DSP.dma.timeconstant = 65536 - (Bit32u) 256000000 / (Bit32u) DSP.dma.param.samplerate;
|
||||
break;
|
||||
|
||||
// set block length
|
||||
case 0x48:
|
||||
// 1,2: lo(blk len) hi(blk len)
|
||||
DSP.datain.getw(&(DSP.dma.blocklength));
|
||||
DSP_B.datain.getw(&(DSP.dma.blocklength));
|
||||
break;
|
||||
|
||||
// 4-bit comp'd, normal DAC DMA, no ref byte
|
||||
case 0x74:
|
||||
// 1,2: lo(length) hi(length)
|
||||
DSP.datain.getw(&length);
|
||||
DSP_B.datain.getw(&length);
|
||||
dsp_dma(0xc0, 0x00, length, 4);
|
||||
break;
|
||||
|
||||
// 4-bit comp'd, normal DAC DMA, 1 ref byte
|
||||
case 0x75:
|
||||
// 1,2: lo(length) hi(length)
|
||||
DSP.datain.getw(&length);
|
||||
DSP_B.datain.getw(&length);
|
||||
dsp_dma(0xc0, 0x00, length, 4|8);
|
||||
break;
|
||||
|
||||
// 3-bit comp'd, normal DAC DMA, no ref byte
|
||||
case 0x76:
|
||||
// 1,2: lo(length) hi(length)
|
||||
DSP.datain.getw(&length);
|
||||
DSP_B.datain.getw(&length);
|
||||
dsp_dma(0xc0, 0x00, length, 3);
|
||||
break;
|
||||
|
||||
// 3-bit comp'd, normal DAC DMA, 1 ref byte
|
||||
case 0x77:
|
||||
// 1,2: lo(length) hi(length)
|
||||
DSP.datain.getw(&length);
|
||||
DSP_B.datain.getw(&length);
|
||||
dsp_dma(0xc0, 0x00, length, 3|8);
|
||||
break;
|
||||
|
||||
@ -1016,7 +1021,7 @@ void bx_sb16_c::dsp_datawrite(Bit32u value)
|
||||
// silence period
|
||||
case 0x80:
|
||||
// 1,2: lo(silence) hi(silence) (len in samples)
|
||||
DSP.datain.getw(&length);
|
||||
DSP_B.datain.getw(&length);
|
||||
// TODO
|
||||
break;
|
||||
|
||||
@ -1093,9 +1098,9 @@ void bx_sb16_c::dsp_datawrite(Bit32u value)
|
||||
case 0xcd:
|
||||
case 0xce:
|
||||
case 0xcf:
|
||||
DSP.datain.get(&mode);
|
||||
DSP.datain.getw(&length);
|
||||
dsp_dma(DSP.datain.currentcommand(), mode, length, 0);
|
||||
DSP_B.datain.get(&mode);
|
||||
DSP_B.datain.getw(&length);
|
||||
dsp_dma(DSP_B.datain.currentcommand(), mode, length, 0);
|
||||
break;
|
||||
|
||||
// pause 8 bit DMA transfer
|
||||
@ -1141,7 +1146,7 @@ void bx_sb16_c::dsp_datawrite(Bit32u value)
|
||||
// read speaker on/off (out ff=on, 00=off)
|
||||
case 0xd8:
|
||||
// none, o1: speaker; ff/00
|
||||
DSP.dataout.put((DSP.speaker == 1)?0xff:0x00);
|
||||
DSP_B.dataout.put((DSP.speaker == 1)?0xff:0x00);
|
||||
break;
|
||||
|
||||
// stop 16 bit auto DMA
|
||||
@ -1166,48 +1171,48 @@ void bx_sb16_c::dsp_datawrite(Bit32u value)
|
||||
|
||||
// DSP identification
|
||||
case 0xe0:
|
||||
DSP.datain.get(&value8);
|
||||
DSP.dataout.put(~value8);
|
||||
DSP_B.datain.get(&value8);
|
||||
DSP_B.dataout.put(~value8);
|
||||
break;
|
||||
|
||||
// get version, out 2 bytes (major, minor)
|
||||
case 0xe1:
|
||||
// none, o1/2: version major.minor
|
||||
DSP.dataout.put(4);
|
||||
if (DSP.dataout.put(5) == 0)
|
||||
DSP_B.dataout.put(4);
|
||||
if (DSP_B.dataout.put(5) == 0)
|
||||
{
|
||||
writelog(WAVELOG(3), "DSP version couldn't be written - buffer overflow");
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xe2:
|
||||
DSP.datain.get(&value8);
|
||||
DSP_B.datain.get(&value8);
|
||||
// TODO
|
||||
writelog(WAVELOG(3), "undocumented DSP command %x ignored (value = 0x%02x)",
|
||||
DSP.datain.currentcommand(), value8);
|
||||
DSP_B.datain.currentcommand(), value8);
|
||||
break;
|
||||
|
||||
case 0xe3:
|
||||
// none, output: Copyright string
|
||||
// the Windows driver needs the exact text, otherwise it
|
||||
// won't load. Same for diagnose.exe
|
||||
DSP.dataout.puts("COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.");
|
||||
DSP.dataout.put(0); // need extra string end
|
||||
DSP_B.dataout.puts("COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.");
|
||||
DSP_B.dataout.put(0); // need extra string end
|
||||
break;
|
||||
|
||||
// write test register
|
||||
case 0xe4:
|
||||
DSP.datain.get(&DSP.testreg);
|
||||
DSP_B.datain.get(&DSP.testreg);
|
||||
break;
|
||||
|
||||
// read test register
|
||||
case 0xe8:
|
||||
DSP.dataout.put(DSP.testreg);
|
||||
DSP_B.dataout.put(DSP.testreg);
|
||||
break;
|
||||
|
||||
// Trigger 8-bit IRQ
|
||||
case 0xf2:
|
||||
DSP.dataout.put(0xaa);
|
||||
DSP_B.dataout.put(0xaa);
|
||||
DSP.irqpending = 1;
|
||||
MIXER.reg[0x82] |= 1; // reg 82 shows the kind of IRQ
|
||||
DEV_pic_raise_irq(BX_SB16_IRQ);
|
||||
@ -1215,30 +1220,30 @@ void bx_sb16_c::dsp_datawrite(Bit32u value)
|
||||
|
||||
// ??? - Win98 needs this
|
||||
case 0xf9:
|
||||
DSP.datain.get(&value8);
|
||||
DSP_B.datain.get(&value8);
|
||||
switch (value8) {
|
||||
case 0x0e:
|
||||
DSP.dataout.put(0xff);
|
||||
DSP_B.dataout.put(0xff);
|
||||
break;
|
||||
case 0x0f:
|
||||
DSP.dataout.put(0x07);
|
||||
DSP_B.dataout.put(0x07);
|
||||
break;
|
||||
case 0x37:
|
||||
DSP.dataout.put(0x38);
|
||||
DSP_B.dataout.put(0x38);
|
||||
break;
|
||||
default:
|
||||
DSP.dataout.put(0x00);
|
||||
DSP_B.dataout.put(0x00);
|
||||
}
|
||||
break;
|
||||
|
||||
// unknown command
|
||||
default:
|
||||
writelog(WAVELOG(3), "unknown DSP command %x, ignored",
|
||||
DSP.datain.currentcommand());
|
||||
DSP_B.datain.currentcommand());
|
||||
break;
|
||||
}
|
||||
DSP.datain.clearcommand();
|
||||
DSP.datain.flush();
|
||||
DSP_B.datain.clearcommand();
|
||||
DSP_B.datain.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1411,7 +1416,7 @@ Bit32u bx_sb16_c::dsp_bufferstatus()
|
||||
Bit32u result = 0x7f;
|
||||
|
||||
// MSB set -> not ready for commands
|
||||
if (DSP.datain.full() == 1) result |= 0x80;
|
||||
if (DSP_B.datain.full() == 1) result |= 0x80;
|
||||
|
||||
writelog(WAVELOG(4), "DSP Buffer status read, result %x", result);
|
||||
|
||||
@ -1435,7 +1440,7 @@ Bit32u bx_sb16_c::dsp_status()
|
||||
}
|
||||
|
||||
// if buffer is not empty, there is data to be read
|
||||
if (DSP.dataout.empty() == 0) result |= 0x80;
|
||||
if (DSP_B.dataout.empty() == 0) result |= 0x80;
|
||||
|
||||
writelog(WAVELOG(4), "DSP output status read, result %x", result);
|
||||
|
||||
@ -1953,11 +1958,11 @@ Bit32u bx_sb16_c::mpu_status()
|
||||
{
|
||||
Bit32u result = 0;
|
||||
|
||||
if ((MPU.datain.full() == 1) ||
|
||||
if ((MPU_B.datain.full() == 1) ||
|
||||
((BX_SB16_THIS midimode & 1) &&
|
||||
(BX_SB16_MIDIOUT1->midiready() == BX_SOUNDLOW_ERR)))
|
||||
result |= 0x40; // output not ready
|
||||
if (MPU.dataout.empty() == 1)
|
||||
if (MPU_B.dataout.empty() == 1)
|
||||
result |= 0x80; // no input available
|
||||
|
||||
writelog(MIDILOG(4), "MPU status port, result %02x", result);
|
||||
@ -1972,30 +1977,30 @@ void bx_sb16_c::mpu_command(Bit32u value)
|
||||
int i;
|
||||
int bytesneeded;
|
||||
|
||||
if (MPU.cmd.hascommand() == 1) // already a command pending, abort that one
|
||||
if (MPU_B.cmd.hascommand() == 1) // already a command pending, abort that one
|
||||
{
|
||||
if ((MPU.cmd.currentcommand() != value) ||
|
||||
(MPU.cmd.commanddone() == 0))
|
||||
if ((MPU_B.cmd.currentcommand() != value) ||
|
||||
(MPU_B.cmd.commanddone() == 0))
|
||||
// it's a different command, or the old one isn't done yet, abort it
|
||||
{
|
||||
MPU.cmd.clearcommand();
|
||||
MPU.cmd.flush();
|
||||
MPU_B.cmd.clearcommand();
|
||||
MPU_B.cmd.flush();
|
||||
}
|
||||
|
||||
// if it's the same one, and we just completed the argument list,
|
||||
// we leave it as it is and process it here
|
||||
}
|
||||
|
||||
if (MPU.cmd.hascommand() == 0) // no command pending, set one up
|
||||
if (MPU_B.cmd.hascommand() == 0) // no command pending, set one up
|
||||
{
|
||||
bytesneeded = 0;
|
||||
if ((value >> 4) == 14) bytesneeded = 1;
|
||||
MPU.cmd.newcommand(value, bytesneeded);
|
||||
MPU_B.cmd.newcommand(value, bytesneeded);
|
||||
}
|
||||
|
||||
if (MPU.cmd.commanddone() == 1) // command is complete, process it
|
||||
if (MPU_B.cmd.commanddone() == 1) // command is complete, process it
|
||||
{
|
||||
switch (MPU.cmd.currentcommand())
|
||||
switch (MPU_B.cmd.currentcommand())
|
||||
{
|
||||
case 0x3f:
|
||||
writelog(MIDILOG(5), "MPU cmd: UART mode on");
|
||||
@ -2018,29 +2023,29 @@ void bx_sb16_c::mpu_command(Bit32u value)
|
||||
MPU.bankmsb[i] = 0;
|
||||
MPU.program[i] = 0;
|
||||
}
|
||||
MPU.cmd.reset();
|
||||
MPU.dataout.reset();
|
||||
MPU.datain.reset();
|
||||
MPU.midicmd.reset();
|
||||
MPU_B.cmd.reset();
|
||||
MPU_B.dataout.reset();
|
||||
MPU_B.datain.reset();
|
||||
MPU_B.midicmd.reset();
|
||||
break;
|
||||
case 0xd0: // d0 and df: prefix for midi command
|
||||
case 0xdf: // like uart mode, but only a single command
|
||||
MPU.singlecommand = 1;
|
||||
writelog(MIDILOG(4), "MPU: prefix %02x received",
|
||||
MPU.cmd.currentcommand());
|
||||
MPU_B.cmd.currentcommand());
|
||||
break;
|
||||
default:
|
||||
writelog(MIDILOG(3), "MPU cmd: unknown command %02x ignored",
|
||||
MPU.cmd.currentcommand());
|
||||
MPU_B.cmd.currentcommand());
|
||||
break;
|
||||
}
|
||||
|
||||
// Need to put an MPU_ACK into the data port if command successful
|
||||
// we'll fake it even if we didn't process the command, so as to
|
||||
// allow detection of the MPU 401.
|
||||
if (MPU.dataout.put(0xfe) == 0)
|
||||
if (MPU_B.dataout.put(0xfe) == 0)
|
||||
writelog(MIDILOG(3), "MPU_ACK error - output buffer full");
|
||||
MPU.cmd.clearcommand(); // clear the command from the buffer
|
||||
MPU_B.cmd.clearcommand(); // clear the command from the buffer
|
||||
}
|
||||
}
|
||||
|
||||
@ -2063,7 +2068,7 @@ Bit32u bx_sb16_c::mpu_dataread()
|
||||
writelog(MIDILOG(4), "MPU IRQ acknowledged");
|
||||
}
|
||||
|
||||
if (MPU.dataout.get(&res8bit) == 0) {
|
||||
if (MPU_B.dataout.get(&res8bit) == 0) {
|
||||
writelog(MIDILOG(3), "MPU data port not ready - no data in buffer");
|
||||
result = 0xff;
|
||||
}
|
||||
@ -2083,12 +2088,12 @@ void bx_sb16_c::mpu_datawrite(Bit32u value)
|
||||
{
|
||||
writelog(MIDILOG(4), "write to MPU data port, value %02x", value);
|
||||
|
||||
if (MPU.cmd.hascommand() == 1)
|
||||
if (MPU_B.cmd.hascommand() == 1)
|
||||
{ // there is a command pending, add arguments to it
|
||||
if (MPU.cmd.put(value) == 0)
|
||||
if (MPU_B.cmd.put(value) == 0)
|
||||
writelog(MIDILOG(3), "MPU Command arguments too long - buffer full");
|
||||
if (MPU.cmd.commanddone() == 1)
|
||||
BX_SB16_THIS mpu_command(MPU.cmd.currentcommand());
|
||||
if (MPU_B.cmd.commanddone() == 1)
|
||||
BX_SB16_THIS mpu_command(MPU_B.cmd.currentcommand());
|
||||
}
|
||||
else if ((MPU.uartmode == 0) && (MPU.singlecommand == 0))
|
||||
{
|
||||
@ -2110,13 +2115,13 @@ void bx_sb16_c::mpu_mididata(Bit32u value)
|
||||
if (value >= 0x80)
|
||||
{ // bit 8 usually denotes a midi command...
|
||||
ismidicommand = 1;
|
||||
if ((value == 0xf7) && (MPU.midicmd.currentcommand() == 0xf0))
|
||||
if ((value == 0xf7) && (MPU_B.midicmd.currentcommand() == 0xf0))
|
||||
// ...except if it is a continuing SYSEX message, then it just
|
||||
// denotes the end of a SYSEX chunk, not the start of a message
|
||||
{
|
||||
ismidicommand = 0; // first, it's not a command
|
||||
MPU.midicmd.newcommand(MPU.midicmd.currentcommand(),
|
||||
MPU.midicmd.bytes());
|
||||
MPU_B.midicmd.newcommand(MPU_B.midicmd.currentcommand(),
|
||||
MPU_B.midicmd.bytes());
|
||||
// Then, set needed bytes to current buffer
|
||||
// because we didn't know the length before
|
||||
}
|
||||
@ -2124,43 +2129,43 @@ void bx_sb16_c::mpu_mididata(Bit32u value)
|
||||
|
||||
if (ismidicommand == 1)
|
||||
{ // this is a command, check if an old one is pending
|
||||
if (MPU.midicmd.hascommand() == 1)
|
||||
if (MPU_B.midicmd.hascommand() == 1)
|
||||
{
|
||||
writelog(MIDILOG(3), "Midi command %02x incomplete, has %d of %d bytes.",
|
||||
MPU.midicmd.currentcommand(), MPU.midicmd.bytes(),
|
||||
MPU.midicmd.commandbytes());
|
||||
MPU_B.midicmd.currentcommand(), MPU_B.midicmd.bytes(),
|
||||
MPU_B.midicmd.commandbytes());
|
||||
// write as much as we can. Should we do this?
|
||||
processmidicommand(0);
|
||||
// clear the pending command
|
||||
MPU.midicmd.clearcommand();
|
||||
MPU.midicmd.flush();
|
||||
MPU_B.midicmd.clearcommand();
|
||||
MPU_B.midicmd.flush();
|
||||
}
|
||||
|
||||
// find the number of arguments to the command
|
||||
static const signed eventlength[] = { 2, 2, 2, 2, 1, 1, 2, 255};
|
||||
// note - length 255 commands have unknown length
|
||||
MPU.midicmd.newcommand(value, eventlength[(value & 0x70) >> 4]);
|
||||
MPU_B.midicmd.newcommand(value, eventlength[(value & 0x70) >> 4]);
|
||||
}
|
||||
else // no command, just arguments to the old command
|
||||
{
|
||||
if (MPU.midicmd.hascommand() == 0)
|
||||
if (MPU_B.midicmd.hascommand() == 0)
|
||||
{ // no command pending, ignore the data
|
||||
writelog(MIDILOG(3), "Midi data %02x received, but no command pending?", value);
|
||||
return;
|
||||
}
|
||||
|
||||
// just some data to the command
|
||||
if (MPU.midicmd.put(value) == 0)
|
||||
if (MPU_B.midicmd.put(value) == 0)
|
||||
writelog(MIDILOG(3), "Midi buffer overflow!");
|
||||
if (MPU.midicmd.commanddone() == 1)
|
||||
if (MPU_B.midicmd.commanddone() == 1)
|
||||
{
|
||||
// the command is complete, process it
|
||||
writelog(MIDILOG(5), "Midi command %02x complete, has %d bytes.",
|
||||
MPU.midicmd.currentcommand(), MPU.midicmd.bytes());
|
||||
MPU_B.midicmd.currentcommand(), MPU_B.midicmd.bytes());
|
||||
processmidicommand(0);
|
||||
// and remove the command from the buffer
|
||||
MPU.midicmd.clearcommand();
|
||||
MPU.midicmd.flush();
|
||||
MPU_B.midicmd.clearcommand();
|
||||
MPU_B.midicmd.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2494,7 +2499,7 @@ int bx_sb16_c::currentdeltatime()
|
||||
return deltatime;
|
||||
}
|
||||
|
||||
// process the midi command stored in MPU.midicmd.to the midi driver
|
||||
// process the midi command stored in MPU_B.midicmd.to the midi driver
|
||||
|
||||
void bx_sb16_c::processmidicommand(bx_bool force)
|
||||
{
|
||||
@ -2502,31 +2507,31 @@ void bx_sb16_c::processmidicommand(bx_bool force)
|
||||
Bit8u value;
|
||||
bx_bool needremap = 0;
|
||||
|
||||
channel = MPU.midicmd.currentcommand() & 0xf;
|
||||
channel = MPU_B.midicmd.currentcommand() & 0xf;
|
||||
|
||||
// we need to log bank changes and program changes
|
||||
if ((MPU.midicmd.currentcommand() >> 4) == 0xc)
|
||||
if ((MPU_B.midicmd.currentcommand() >> 4) == 0xc)
|
||||
{ // a program change
|
||||
value = MPU.midicmd.peek(0);
|
||||
value = MPU_B.midicmd.peek(0);
|
||||
writelog(MIDILOG(1), "* ProgramChange channel %d to %d",
|
||||
channel, value);
|
||||
MPU.program[channel] = value;
|
||||
needremap = 1;
|
||||
}
|
||||
else if ((MPU.midicmd.currentcommand() >> 4) == 0xb)
|
||||
else if ((MPU_B.midicmd.currentcommand() >> 4) == 0xb)
|
||||
{ // a control change, could be a bank change
|
||||
if (MPU.midicmd.peek(0) == 0)
|
||||
if (MPU_B.midicmd.peek(0) == 0)
|
||||
{ // bank select MSB
|
||||
value = MPU.midicmd.peek(1);
|
||||
value = MPU_B.midicmd.peek(1);
|
||||
writelog(MIDILOG(1), "* BankSelectMSB (%x %x %x) channel %d to %d",
|
||||
MPU.midicmd.peek(0), MPU.midicmd.peek(1), MPU.midicmd.peek(2),
|
||||
MPU_B.midicmd.peek(0), MPU_B.midicmd.peek(1), MPU_B.midicmd.peek(2),
|
||||
channel, value);
|
||||
MPU.bankmsb[channel] = value;
|
||||
needremap = 1;
|
||||
}
|
||||
else if (MPU.midicmd.peek(0) == 32)
|
||||
else if (MPU_B.midicmd.peek(0) == 32)
|
||||
{ // bank select LSB
|
||||
value = MPU.midicmd.peek(1);
|
||||
value = MPU_B.midicmd.peek(1);
|
||||
writelog(MIDILOG(1), "* BankSelectLSB channel %d to %d",
|
||||
channel, value);
|
||||
MPU.banklsb[channel] = value;
|
||||
@ -2536,10 +2541,10 @@ void bx_sb16_c::processmidicommand(bx_bool force)
|
||||
|
||||
Bit8u temparray[256];
|
||||
i = 0;
|
||||
while (MPU.midicmd.empty() == 0)
|
||||
MPU.midicmd.get(&(temparray[i++]));
|
||||
while (MPU_B.midicmd.empty() == 0)
|
||||
MPU_B.midicmd.get(&(temparray[i++]));
|
||||
|
||||
writemidicommand(MPU.midicmd.currentcommand(), i, temparray);
|
||||
writemidicommand(MPU_B.midicmd.currentcommand(), i, temparray);
|
||||
|
||||
// if single command, revert to command mode
|
||||
if (MPU.singlecommand != 0)
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2018 The Bochs Project
|
||||
// Copyright (C) 2001-2020 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -164,53 +164,61 @@ private:
|
||||
|
||||
// the MPU 401 relevant variables
|
||||
struct bx_sb16_mpu_struct {
|
||||
bx_sb16_buffer datain, dataout, cmd, midicmd;
|
||||
bx_bool uartmode, irqpending, forceuartmode, singlecommand;
|
||||
struct {
|
||||
bx_sb16_buffer datain, dataout, cmd, midicmd;
|
||||
} b;
|
||||
struct {
|
||||
bx_bool uartmode, irqpending, forceuartmode, singlecommand;
|
||||
|
||||
int banklsb[16];
|
||||
int bankmsb[16]; // current patch lists
|
||||
int program[16];
|
||||
int banklsb[16];
|
||||
int bankmsb[16]; // current patch lists
|
||||
int program[16];
|
||||
|
||||
int timer_handle, current_timer; // no. of delta times passed
|
||||
Bit32u last_delta_time; // timer value at last command
|
||||
Bit8u outputinit;
|
||||
int timer_handle, current_timer; // no. of delta times passed
|
||||
Bit32u last_delta_time; // timer value at last command
|
||||
Bit8u outputinit;
|
||||
} d;
|
||||
} mpu401;
|
||||
|
||||
// the DSP variables
|
||||
struct bx_sb16_dsp_struct {
|
||||
bx_sb16_buffer datain, dataout;
|
||||
Bit8u resetport; // last value written to the reset port
|
||||
Bit8u speaker,prostereo; // properties of the sound input/output
|
||||
bx_bool irqpending; // Is an IRQ pending (not ack'd)
|
||||
bx_bool midiuartmode; // Is the DSP in MIDI UART mode
|
||||
bx_bool nondma_mode; // Set if DSP command 0x10 active
|
||||
Bit32u nondma_count; // Number of samples sent in non-DMA mode
|
||||
Bit8u samplebyte; // Current data byte in non-DMA mode
|
||||
Bit8u testreg;
|
||||
struct bx_sb16_dsp_dma_struct {
|
||||
// Properties of the current DMA transfer:
|
||||
// mode= 0: no transfer, 1: single-cycle transfer, 2: auto-init DMA
|
||||
// bits= 8 or 16
|
||||
// fifo= ?? Bit used in DMA command, no idea what it means...
|
||||
// output= 0: input, 1: output
|
||||
// bps= bytes per sample; =(dmabits/8)*(dmastereo+1)
|
||||
// stereo= 0: mono, 1: stereo
|
||||
// issigned= 0: unsigned data, 1: signed data
|
||||
// highspeed= 0: normal mode, 1: highspeed mode (only SBPro)
|
||||
// timer= so many us between data bytes
|
||||
int mode, bps, timer;
|
||||
bx_bool fifo, output, highspeed;
|
||||
bx_pcm_param_t param;
|
||||
Bit16u count; // bytes remaining in this transfer
|
||||
Bit8u *chunk; // buffers up to BX_SOUNDLOW_WAVEPACKETSIZE bytes
|
||||
int chunkindex; // index into the buffer
|
||||
int chunkcount; // for input: size of the recorded input
|
||||
Bit16u timeconstant;
|
||||
Bit16u blocklength;
|
||||
} dma;
|
||||
int timer_handle; // handle for the DMA timer
|
||||
Bit8u outputinit; // have the lowlevel output been initialized
|
||||
bx_bool inputinit; // have the lowlevel input been initialized
|
||||
struct {
|
||||
bx_sb16_buffer datain, dataout;
|
||||
} b;
|
||||
struct {
|
||||
Bit8u resetport; // last value written to the reset port
|
||||
Bit8u speaker,prostereo; // properties of the sound input/output
|
||||
bx_bool irqpending; // Is an IRQ pending (not ack'd)
|
||||
bx_bool midiuartmode; // Is the DSP in MIDI UART mode
|
||||
bx_bool nondma_mode; // Set if DSP command 0x10 active
|
||||
Bit32u nondma_count; // Number of samples sent in non-DMA mode
|
||||
Bit8u samplebyte; // Current data byte in non-DMA mode
|
||||
Bit8u testreg;
|
||||
struct bx_sb16_dsp_dma_struct {
|
||||
// Properties of the current DMA transfer:
|
||||
// mode= 0: no transfer, 1: single-cycle transfer, 2: auto-init DMA
|
||||
// bits= 8 or 16
|
||||
// fifo= ?? Bit used in DMA command, no idea what it means...
|
||||
// output= 0: input, 1: output
|
||||
// bps= bytes per sample; =(dmabits/8)*(dmastereo+1)
|
||||
// stereo= 0: mono, 1: stereo
|
||||
// issigned= 0: unsigned data, 1: signed data
|
||||
// highspeed= 0: normal mode, 1: highspeed mode (only SBPro)
|
||||
// timer= so many us between data bytes
|
||||
int mode, bps, timer;
|
||||
bx_bool fifo, output, highspeed;
|
||||
bx_pcm_param_t param;
|
||||
Bit16u count; // bytes remaining in this transfer
|
||||
Bit8u *chunk; // buffers up to BX_SOUNDLOW_WAVEPACKETSIZE bytes
|
||||
int chunkindex; // index into the buffer
|
||||
int chunkcount; // for input: size of the recorded input
|
||||
Bit16u timeconstant;
|
||||
Bit16u blocklength;
|
||||
} dma;
|
||||
int timer_handle; // handle for the DMA timer
|
||||
Bit8u outputinit; // have the lowlevel output been initialized
|
||||
bx_bool inputinit; // have the lowlevel input been initialized
|
||||
} d;
|
||||
} dsp;
|
||||
|
||||
// the ASP/CSP registers
|
||||
@ -270,7 +278,8 @@ private:
|
||||
BX_SB16_SMF void dsp_enabledma(); // enable the transfer
|
||||
BX_SB16_SMF void dsp_disabledma(); // temporarily disable DMA
|
||||
BX_SB16_SMF void dsp_disable_nondma(); // disable DSP direct mode
|
||||
static void dsp_dmatimer(void *);
|
||||
static void dsp_dmatimer_handler(void *);
|
||||
void dsp_dmatimer(void);
|
||||
static Bit32u sb16_adc_handler(void *, Bit32u len);
|
||||
Bit32u dsp_adc_handler(Bit32u len);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user