- implemented "fast-dma" support for 16 bit and in the SB16
- TODO: fix BX_DBG_DMA_REPORT
This commit is contained in:
parent
b225c158a9
commit
85a914c9e9
@ -663,8 +663,7 @@ void bx_dma_c::raise_HLDA(void)
|
||||
bx_phy_address phy_addr;
|
||||
bx_bool ma_sl = 0;
|
||||
Bit16u maxlen, len = 1;
|
||||
Bit8u buffer[512];
|
||||
Bit16u data_word;
|
||||
Bit8u buffer[BX_DMA_BUFFER_SIZE];
|
||||
|
||||
BX_DMA_THIS HLDA = 1;
|
||||
// find highest priority channel
|
||||
@ -694,18 +693,18 @@ void bx_dma_c::raise_HLDA(void)
|
||||
(BX_DMA_THIS s[ma_sl].chan[channel].current_address << ma_sl);
|
||||
|
||||
if (!BX_DMA_THIS s[ma_sl].chan[channel].mode.address_decrement) {
|
||||
maxlen = BX_DMA_THIS s[ma_sl].chan[channel].current_count + 1;
|
||||
BX_DMA_THIS TC = (maxlen <= 512);
|
||||
if (maxlen > 512) {
|
||||
maxlen = 512;
|
||||
maxlen = (BX_DMA_THIS s[ma_sl].chan[channel].current_count + 1) << ma_sl;
|
||||
BX_DMA_THIS TC = (maxlen <= BX_DMA_BUFFER_SIZE);
|
||||
if (maxlen > BX_DMA_BUFFER_SIZE) {
|
||||
maxlen = BX_DMA_BUFFER_SIZE;
|
||||
}
|
||||
} else {
|
||||
BX_DMA_THIS TC = (BX_DMA_THIS s[ma_sl].chan[channel].current_count == 0);
|
||||
maxlen = 1;
|
||||
maxlen = 1 << ma_sl;
|
||||
}
|
||||
|
||||
if (BX_DMA_THIS s[ma_sl].chan[channel].mode.transfer_type == 1) { // write
|
||||
// DMA controlled xfer of byte from I/O to Memory
|
||||
// DMA controlled xfer of bytes from I/O to Memory
|
||||
|
||||
if (!ma_sl) {
|
||||
if (BX_DMA_THIS h[channel].dmaWrite8)
|
||||
@ -715,19 +714,19 @@ void bx_dma_c::raise_HLDA(void)
|
||||
|
||||
DEV_MEM_WRITE_PHYSICAL_DMA(phy_addr, len, buffer);
|
||||
|
||||
BX_DBG_DMA_REPORT(phy_addr, 1, BX_WRITE, buffer[0]);
|
||||
BX_DBG_DMA_REPORT(phy_addr, len, BX_WRITE, buffer[0]); // FIXME
|
||||
} else {
|
||||
if (BX_DMA_THIS h[channel].dmaWrite16)
|
||||
len = BX_DMA_THIS h[channel].dmaWrite16(&data_word, 1);
|
||||
len = BX_DMA_THIS h[channel].dmaWrite16((Bit16u*)buffer, maxlen / 2);
|
||||
else
|
||||
BX_PANIC(("no dmaWrite handler for channel %u.", channel));
|
||||
|
||||
DEV_MEM_WRITE_PHYSICAL(phy_addr, 2, (Bit8u*) &data_word);
|
||||
DEV_MEM_WRITE_PHYSICAL_DMA(phy_addr, len, buffer);
|
||||
|
||||
BX_DBG_DMA_REPORT(phy_addr, 2, BX_WRITE, data_word);
|
||||
BX_DBG_DMA_REPORT(phy_addr, len * 2, BX_WRITE, buffer[0] | (buffer[1] << 16)); // FIXME
|
||||
}
|
||||
} else if (BX_DMA_THIS s[ma_sl].chan[channel].mode.transfer_type == 2) { // read
|
||||
// DMA controlled xfer of byte from Memory to I/O
|
||||
// DMA controlled xfer of bytes from Memory to I/O
|
||||
|
||||
if (!ma_sl) {
|
||||
DEV_MEM_READ_PHYSICAL_DMA(phy_addr, maxlen, buffer);
|
||||
@ -735,14 +734,14 @@ void bx_dma_c::raise_HLDA(void)
|
||||
if (BX_DMA_THIS h[channel].dmaRead8)
|
||||
len = BX_DMA_THIS h[channel].dmaRead8(buffer, maxlen);
|
||||
|
||||
BX_DBG_DMA_REPORT(phy_addr, 1, BX_READ, buffer[0]);
|
||||
BX_DBG_DMA_REPORT(phy_addr, len, BX_READ, buffer[0]); // FIXME
|
||||
} else {
|
||||
DEV_MEM_READ_PHYSICAL(phy_addr, 2, (Bit8u*) &data_word);
|
||||
DEV_MEM_READ_PHYSICAL_DMA(phy_addr, maxlen, buffer);
|
||||
|
||||
if (BX_DMA_THIS h[channel].dmaRead16)
|
||||
len = BX_DMA_THIS h[channel].dmaRead16(&data_word, 1);
|
||||
len = BX_DMA_THIS h[channel].dmaRead16((Bit16u*)buffer, maxlen / 2);
|
||||
|
||||
BX_DBG_DMA_REPORT(phy_addr, 2, BX_READ, data_word);
|
||||
BX_DBG_DMA_REPORT(phy_addr, len * 2, BX_READ, buffer[0] | (buffer[1] << 16)); // FIXME
|
||||
}
|
||||
} else if (BX_DMA_THIS s[ma_sl].chan[channel].mode.transfer_type == 0) {
|
||||
// verify
|
||||
@ -754,7 +753,7 @@ void bx_dma_c::raise_HLDA(void)
|
||||
BX_PANIC(("no dmaWrite handler for channel %u.", channel));
|
||||
} else {
|
||||
if (BX_DMA_THIS h[channel].dmaWrite16)
|
||||
len = BX_DMA_THIS h[channel].dmaWrite16(&data_word, 1);
|
||||
len = BX_DMA_THIS h[channel].dmaWrite16((Bit16u*)buffer, 1);
|
||||
else
|
||||
BX_PANIC(("no dmaWrite handler for channel %u.", channel));
|
||||
}
|
||||
|
@ -37,6 +37,9 @@
|
||||
/* size of internal buffer for mouse devices */
|
||||
#define BX_MOUSE_BUFF_SIZE 48
|
||||
|
||||
/* maximum size of the ISA DMA buffer */
|
||||
#define BX_DMA_BUFFER_SIZE 512
|
||||
|
||||
typedef Bit32u (*bx_read_handler_t)(void *, Bit32u, unsigned);
|
||||
typedef void (*bx_write_handler_t)(void *, Bit32u, Bit32u, unsigned);
|
||||
|
||||
|
@ -1286,10 +1286,10 @@ void bx_sb16_c::dsp_dma(Bit8u command, Bit8u mode, Bit16u length, Bit8u comp)
|
||||
Bit32u sampledatarate = (Bit32u) DSP.dma.samplerate * (Bit32u) DSP.dma.bps;
|
||||
if ((DSP.dma.bits == 16) && (BX_SB16_DMAH != 0)) {
|
||||
DSP.dma.count = (DSP.dma.blocklength + 1) * (DSP.dma.bps / 2) - 1;
|
||||
DSP.dma.timer = BX_SB16_THIS dmatimer / (sampledatarate / 2);
|
||||
DSP.dma.timer = BX_SB16_THIS dmatimer / (sampledatarate / 2) * BX_DMA_BUFFER_SIZE;
|
||||
} else {
|
||||
DSP.dma.count = (DSP.dma.blocklength + 1) * DSP.dma.bps - 1;
|
||||
DSP.dma.timer = BX_SB16_THIS dmatimer / sampledatarate;
|
||||
DSP.dma.timer = BX_SB16_THIS dmatimer / sampledatarate * BX_DMA_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
writelog(WAVELOG(5), "DMA is %db, %dHz, %s, %s, mode %d, %s, %s, %d bps, %d usec/DMA",
|
||||
@ -1564,82 +1564,92 @@ void bx_sb16_c::dsp_dmadone()
|
||||
// now the actual transfer routines, called by the DMA controller
|
||||
// note that read = from application to soundcard (output),
|
||||
// and write = from soundcard to application (input)
|
||||
Bit16u bx_sb16_c::dma_read8(Bit8u *data_byte, Bit16u maxlen)
|
||||
Bit16u bx_sb16_c::dma_read8(Bit8u *buffer, Bit16u maxlen)
|
||||
{
|
||||
Bit16u len = 0;
|
||||
|
||||
DEV_dma_set_drq(BX_SB16_DMAL, 0); // the timer will raise it again
|
||||
|
||||
if (DSP.dma.count % 100 == 0) // otherwise it's just too many lines of log
|
||||
writelog(WAVELOG(5), "Received 8-bit DMA %2x, %d remaining ",
|
||||
*data_byte, DSP.dma.count);
|
||||
DSP.dma.count--;
|
||||
writelog(WAVELOG(5), "Received 8-bit DMA: 0x%02x, %d remaining ",
|
||||
buffer[0], DSP.dma.count);
|
||||
|
||||
dsp_getsamplebyte(*data_byte);
|
||||
do {
|
||||
dsp_getsamplebyte(buffer[len++]);
|
||||
DSP.dma.count--;
|
||||
} while ((len < maxlen) && (DSP.dma.count != 0xffff));
|
||||
|
||||
if (DSP.dma.count == 0xffff) // last byte received
|
||||
dsp_dmadone();
|
||||
|
||||
return 1;
|
||||
return len;
|
||||
}
|
||||
|
||||
Bit16u bx_sb16_c::dma_write8(Bit8u *data_byte, Bit16u maxlen)
|
||||
Bit16u bx_sb16_c::dma_write8(Bit8u *buffer, Bit16u maxlen)
|
||||
{
|
||||
Bit16u len = 0;
|
||||
|
||||
DEV_dma_set_drq(BX_SB16_DMAL, 0); // the timer will raise it again
|
||||
|
||||
DSP.dma.count--;
|
||||
do {
|
||||
buffer[len++] = dsp_putsamplebyte();
|
||||
DSP.dma.count--;
|
||||
} while ((len < maxlen) && (DSP.dma.count != 0xffff));
|
||||
|
||||
*data_byte = dsp_putsamplebyte();
|
||||
|
||||
if (DSP.dma.count % 100 == 0) // otherwise it's just too many lines of log
|
||||
writelog(WAVELOG(5), "Sent 8-bit DMA %2x, %d remaining ",
|
||||
*data_byte, DSP.dma.count);
|
||||
writelog(WAVELOG(5), "Sent 8-bit DMA: 0x%02x, %d remaining ",
|
||||
buffer[0], DSP.dma.count);
|
||||
|
||||
if (DSP.dma.count == 0xffff) // last byte sent
|
||||
dsp_dmadone();
|
||||
|
||||
return 1;
|
||||
return len;
|
||||
}
|
||||
|
||||
Bit16u bx_sb16_c::dma_read16(Bit16u *data_word, Bit16u maxlen)
|
||||
Bit16u bx_sb16_c::dma_read16(Bit16u *buffer, Bit16u maxlen)
|
||||
{
|
||||
Bit16u len = 0;
|
||||
Bit8u *buf8;
|
||||
|
||||
DEV_dma_set_drq(BX_SB16_DMAH, 0); // the timer will raise it again
|
||||
|
||||
if (DSP.dma.count % 100 == 0) // otherwise it's just too many lines of log
|
||||
writelog(WAVELOG(5), "Received 16-bit DMA %04x, %d remaining ",
|
||||
*data_word, DSP.dma.count);
|
||||
writelog(WAVELOG(5), "Received 16-bit DMA: 0x%04x, %d remaining ",
|
||||
buffer[0], DSP.dma.count);
|
||||
|
||||
DSP.dma.count--;
|
||||
|
||||
dsp_getsamplebyte(*data_word & 0xff);
|
||||
dsp_getsamplebyte(*data_word >> 8);
|
||||
do {
|
||||
buf8 = (Bit8u*)(buffer+len);
|
||||
dsp_getsamplebyte(buf8[0]);
|
||||
dsp_getsamplebyte(buf8[1]);
|
||||
len++;
|
||||
DSP.dma.count--;
|
||||
} while ((len < maxlen) && (DSP.dma.count != 0xffff));
|
||||
|
||||
if (DSP.dma.count == 0xffff) // last word received
|
||||
dsp_dmadone();
|
||||
|
||||
return 1;
|
||||
return len;
|
||||
}
|
||||
|
||||
Bit16u bx_sb16_c::dma_write16(Bit16u *data_word, Bit16u maxlen)
|
||||
Bit16u bx_sb16_c::dma_write16(Bit16u *buffer, Bit16u maxlen)
|
||||
{
|
||||
Bit8u byte1, byte2;
|
||||
Bit16u len = 0;
|
||||
Bit8u *buf8;
|
||||
|
||||
DEV_dma_set_drq(BX_SB16_DMAH, 0); // the timer will raise it again
|
||||
|
||||
DSP.dma.count--;
|
||||
do {
|
||||
buf8 = (Bit8u*)(buffer+len);
|
||||
buf8[0] = dsp_putsamplebyte();
|
||||
buf8[1] = dsp_putsamplebyte();
|
||||
len++;
|
||||
DSP.dma.count--;
|
||||
} while ((len < maxlen) && (DSP.dma.count != 0xffff));
|
||||
|
||||
byte1 = dsp_putsamplebyte();
|
||||
byte2 = dsp_putsamplebyte();
|
||||
|
||||
// all input is in little endian
|
||||
*data_word = byte1 | (byte2 << 8);
|
||||
|
||||
if (DSP.dma.count % 100 == 0) // otherwise it's just too many lines of log
|
||||
writelog(WAVELOG(5), "Sent 16-bit DMA %4x, %d remaining ",
|
||||
*data_word, DSP.dma.count);
|
||||
writelog(WAVELOG(5), "Sent 16-bit DMA: 0x%4x, %d remaining ",
|
||||
buffer[0], DSP.dma.count);
|
||||
|
||||
if (DSP.dma.count == 0xffff) // last word sent
|
||||
dsp_dmadone();
|
||||
|
||||
return 1;
|
||||
return len;
|
||||
}
|
||||
|
||||
// the mixer, supported type is CT1745 (as in an SB16)
|
||||
|
@ -286,10 +286,10 @@ private:
|
||||
} emuldata;
|
||||
|
||||
/* DMA input and output, 8 and 16 bit */
|
||||
BX_SB16_SMF Bit16u dma_write8(Bit8u *data_byte, Bit16u maxlen);
|
||||
BX_SB16_SMF Bit16u dma_read8(Bit8u *data_byte, Bit16u maxlen);
|
||||
BX_SB16_SMF Bit16u dma_write16(Bit16u *data_word, Bit16u maxlen);
|
||||
BX_SB16_SMF Bit16u dma_read16(Bit16u *data_word, Bit16u maxlen);
|
||||
BX_SB16_SMF Bit16u dma_write8(Bit8u *buffer, Bit16u maxlen);
|
||||
BX_SB16_SMF Bit16u dma_read8(Bit8u *buffer, Bit16u maxlen);
|
||||
BX_SB16_SMF Bit16u dma_write16(Bit16u *buffer, Bit16u maxlen);
|
||||
BX_SB16_SMF Bit16u dma_read16(Bit16u *buffer, Bit16u maxlen);
|
||||
|
||||
/* the MPU 401 part of the emulator */
|
||||
BX_SB16_SMF Bit32u mpu_status(); // read status port 3x1
|
||||
|
Loading…
Reference in New Issue
Block a user