diff --git a/bochs/iodev/dma.cc b/bochs/iodev/dma.cc index f4144f1c8..74cee61a5 100644 --- a/bochs/iodev/dma.cc +++ b/bochs/iodev/dma.cc @@ -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)); } diff --git a/bochs/iodev/iodev.h b/bochs/iodev/iodev.h index f6fbfe1a5..1ed20b6cb 100644 --- a/bochs/iodev/iodev.h +++ b/bochs/iodev/iodev.h @@ -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); diff --git a/bochs/iodev/sound/sb16.cc b/bochs/iodev/sound/sb16.cc index bb57b7207..ae57a17b6 100644 --- a/bochs/iodev/sound/sb16.cc +++ b/bochs/iodev/sound/sb16.cc @@ -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) diff --git a/bochs/iodev/sound/sb16.h b/bochs/iodev/sound/sb16.h index 32ca48eb7..fe096fe23 100644 --- a/bochs/iodev/sound/sb16.h +++ b/bochs/iodev/sound/sb16.h @@ -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