diff --git a/bochs/iodev/dma.cc b/bochs/iodev/dma.cc index 5dc6c58ee..f4144f1c8 100644 --- a/bochs/iodev/dma.cc +++ b/bochs/iodev/dma.cc @@ -66,8 +66,8 @@ bx_dma_c::~bx_dma_c() } unsigned bx_dma_c::registerDMA8Channel(unsigned channel, - void (* dmaRead)(Bit8u *data_byte), - void (* dmaWrite)(Bit8u *data_byte), + Bit16u (* dmaRead)(Bit8u *data_byte, Bit16u maxlen), + Bit16u (* dmaWrite)(Bit8u *data_byte, Bit16u maxlen), const char *name) { if (channel > 3) { @@ -86,8 +86,8 @@ unsigned bx_dma_c::registerDMA8Channel(unsigned channel, } unsigned bx_dma_c::registerDMA16Channel(unsigned channel, - void (* dmaRead)(Bit16u *data_word), - void (* dmaWrite)(Bit16u *data_word), + Bit16u (* dmaRead)(Bit16u *data_word, Bit16u maxlen), + Bit16u (* dmaWrite)(Bit16u *data_word, Bit16u maxlen), const char *name) { if ((channel < 4) || (channel > 7)) { @@ -661,8 +661,10 @@ void bx_dma_c::raise_HLDA(void) { unsigned channel; bx_phy_address phy_addr; - bx_bool count_expired = 0; bx_bool ma_sl = 0; + Bit16u maxlen, len = 1; + Bit8u buffer[512]; + Bit16u data_word; BX_DMA_THIS HLDA = 1; // find highest priority channel @@ -691,53 +693,32 @@ void bx_dma_c::raise_HLDA(void) phy_addr = (BX_DMA_THIS s[ma_sl].chan[channel].page_reg << 16) | (BX_DMA_THIS s[ma_sl].chan[channel].current_address << ma_sl); - BX_DMA_THIS s[ma_sl].DACK[channel] = 1; - // check for expiration of count, so we can signal TC and DACK(n) - // at the same time. - if (BX_DMA_THIS s[ma_sl].chan[channel].mode.address_decrement==0) - BX_DMA_THIS s[ma_sl].chan[channel].current_address++; - else - BX_DMA_THIS s[ma_sl].chan[channel].current_address--; - BX_DMA_THIS s[ma_sl].chan[channel].current_count--; - if (BX_DMA_THIS s[ma_sl].chan[channel].current_count == 0xffff) { - // count expired, done with transfer - // assert TC, deassert HRQ & DACK(n) lines - BX_DMA_THIS s[ma_sl].status_reg |= (1 << channel); // hold TC in status reg - BX_DMA_THIS TC = 1; - count_expired = 1; - if (BX_DMA_THIS s[ma_sl].chan[channel].mode.autoinit_enable == 0) { - // set mask bit if not in autoinit mode - BX_DMA_THIS s[ma_sl].mask[channel] = 1; - } - else { - // count expired, but in autoinit mode - // reload count and base address - BX_DMA_THIS s[ma_sl].chan[channel].current_address = - BX_DMA_THIS s[ma_sl].chan[channel].base_address; - BX_DMA_THIS s[ma_sl].chan[channel].current_count = - BX_DMA_THIS s[ma_sl].chan[channel].base_count; + 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; } + } else { + BX_DMA_THIS TC = (BX_DMA_THIS s[ma_sl].chan[channel].current_count == 0); + maxlen = 1; } - Bit8u data_byte; - Bit16u data_word; - if (BX_DMA_THIS s[ma_sl].chan[channel].mode.transfer_type == 1) { // write // DMA controlled xfer of byte from I/O to Memory if (!ma_sl) { if (BX_DMA_THIS h[channel].dmaWrite8) - BX_DMA_THIS h[channel].dmaWrite8(&data_byte); + len = BX_DMA_THIS h[channel].dmaWrite8(buffer, maxlen); else BX_PANIC(("no dmaWrite handler for channel %u.", channel)); - DEV_MEM_WRITE_PHYSICAL(phy_addr, 1, &data_byte); + DEV_MEM_WRITE_PHYSICAL_DMA(phy_addr, len, buffer); - BX_DBG_DMA_REPORT(phy_addr, 1, BX_WRITE, data_byte); - } - else { + BX_DBG_DMA_REPORT(phy_addr, 1, BX_WRITE, buffer[0]); + } else { if (BX_DMA_THIS h[channel].dmaWrite16) - BX_DMA_THIS h[channel].dmaWrite16(&data_word); + len = BX_DMA_THIS h[channel].dmaWrite16(&data_word, 1); else BX_PANIC(("no dmaWrite handler for channel %u.", channel)); @@ -745,48 +726,65 @@ void bx_dma_c::raise_HLDA(void) BX_DBG_DMA_REPORT(phy_addr, 2, BX_WRITE, data_word); } - } - else if (BX_DMA_THIS s[ma_sl].chan[channel].mode.transfer_type == 2) { // read + } 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 if (!ma_sl) { - DEV_MEM_READ_PHYSICAL(phy_addr, 1, &data_byte); + DEV_MEM_READ_PHYSICAL_DMA(phy_addr, maxlen, buffer); if (BX_DMA_THIS h[channel].dmaRead8) - BX_DMA_THIS h[channel].dmaRead8(&data_byte); + len = BX_DMA_THIS h[channel].dmaRead8(buffer, maxlen); - BX_DBG_DMA_REPORT(phy_addr, 1, BX_READ, data_byte); - } - else { + BX_DBG_DMA_REPORT(phy_addr, 1, BX_READ, buffer[0]); + } else { DEV_MEM_READ_PHYSICAL(phy_addr, 2, (Bit8u*) &data_word); if (BX_DMA_THIS h[channel].dmaRead16) - BX_DMA_THIS h[channel].dmaRead16(&data_word); + len = BX_DMA_THIS h[channel].dmaRead16(&data_word, 1); BX_DBG_DMA_REPORT(phy_addr, 2, BX_READ, data_word); } - } - else if (BX_DMA_THIS s[ma_sl].chan[channel].mode.transfer_type == 0) { + } else if (BX_DMA_THIS s[ma_sl].chan[channel].mode.transfer_type == 0) { // verify if (!ma_sl) { if (BX_DMA_THIS h[channel].dmaWrite8) - BX_DMA_THIS h[channel].dmaWrite8(&data_byte); + len = BX_DMA_THIS h[channel].dmaWrite8(buffer, 1); else BX_PANIC(("no dmaWrite handler for channel %u.", channel)); - } - else { + } else { if (BX_DMA_THIS h[channel].dmaWrite16) - BX_DMA_THIS h[channel].dmaWrite16(&data_word); + len = BX_DMA_THIS h[channel].dmaWrite16(&data_word, 1); else BX_PANIC(("no dmaWrite handler for channel %u.", channel)); } - } - else { + } else { BX_PANIC(("hlda: transfer_type 3 is undefined")); } - if (count_expired) { + BX_DMA_THIS s[ma_sl].DACK[channel] = 1; + // check for expiration of count, so we can signal TC and DACK(n) + // at the same time. + if (!BX_DMA_THIS s[ma_sl].chan[channel].mode.address_decrement) + BX_DMA_THIS s[ma_sl].chan[channel].current_address += len; + else + BX_DMA_THIS s[ma_sl].chan[channel].current_address--; + BX_DMA_THIS s[ma_sl].chan[channel].current_count -= len; + if (BX_DMA_THIS s[ma_sl].chan[channel].current_count == 0xffff) { + // count expired, done with transfer + // assert TC, deassert HRQ & DACK(n) lines + BX_DMA_THIS s[ma_sl].status_reg |= (1 << channel); // hold TC in status reg + if (BX_DMA_THIS s[ma_sl].chan[channel].mode.autoinit_enable == 0) { + // set mask bit if not in autoinit mode + BX_DMA_THIS s[ma_sl].mask[channel] = 1; + } else { + // count expired, but in autoinit mode + // reload count and base address + BX_DMA_THIS s[ma_sl].chan[channel].current_address = + BX_DMA_THIS s[ma_sl].chan[channel].base_address; + BX_DMA_THIS s[ma_sl].chan[channel].current_count = + BX_DMA_THIS s[ma_sl].chan[channel].base_count; + } BX_DMA_THIS TC = 0; // clear TC, adapter card already notified BX_DMA_THIS HLDA = 0; bx_pc_system.set_HRQ(0); // clear HRQ to CPU diff --git a/bochs/iodev/dma.h b/bochs/iodev/dma.h index 7ff34986d..48180186d 100644 --- a/bochs/iodev/dma.h +++ b/bochs/iodev/dma.h @@ -46,12 +46,12 @@ public: #endif virtual unsigned registerDMA8Channel(unsigned channel, - void (* dmaRead)(Bit8u *data_byte), - void (* dmaWrite)(Bit8u *data_byte), + Bit16u (* dmaRead)(Bit8u *data_byte, Bit16u maxlen), + Bit16u (* dmaWrite)(Bit8u *data_byte, Bit16u maxlen), const char *name); virtual unsigned registerDMA16Channel(unsigned channel, - void (* dmaRead)(Bit16u *data_word), - void (* dmaWrite)(Bit16u *data_word), + Bit16u (* dmaRead)(Bit16u *data_word, Bit16u maxlen), + Bit16u (* dmaWrite)(Bit16u *data_word, Bit16u maxlen), const char *name); virtual unsigned unregisterDMAChannel(unsigned channel); @@ -97,10 +97,10 @@ private: Bit8u ext_page_reg[16]; // Extra page registers (unused) struct { - void (* dmaRead8)(Bit8u *data_byte); - void (* dmaWrite8)(Bit8u *data_byte); - void (* dmaRead16)(Bit16u *data_word); - void (* dmaWrite16)(Bit16u *data_word); + Bit16u (* dmaRead8)(Bit8u *data_byte, Bit16u maxlen); + Bit16u (* dmaWrite8)(Bit8u *data_byte, Bit16u maxlen); + Bit16u (* dmaRead16)(Bit16u *data_word, Bit16u maxlen); + Bit16u (* dmaWrite16)(Bit16u *data_word, Bit16u maxlen); } h[4]; // DMA read and write handlers }; diff --git a/bochs/iodev/floppy.cc b/bochs/iodev/floppy.cc index e94e10443..6f9da0fe9 100644 --- a/bochs/iodev/floppy.cc +++ b/bochs/iodev/floppy.cc @@ -444,7 +444,7 @@ Bit32u bx_floppy_ctrl_c::read(Bit32u address, unsigned io_len) case 0x3F5: /* diskette controller data */ if ((BX_FD_THIS s.main_status_reg & FD_MS_NDMA) && ((BX_FD_THIS s.pending_command & 0x4f) == 0x46)) { - dma_write(&value); + dma_write(&value, 1); lower_interrupt(); // don't enter idle phase until we've given CPU last data byte if (BX_FD_THIS s.TC) enter_idle_phase(); @@ -603,7 +603,7 @@ void bx_floppy_ctrl_c::write(Bit32u address, Bit32u value, unsigned io_len) case 0x3F5: /* diskette controller data */ BX_DEBUG(("command = 0x%02x", (unsigned) value)); if ((BX_FD_THIS s.main_status_reg & FD_MS_NDMA) && ((BX_FD_THIS s.pending_command & 0x4f) == 0x45)) { - BX_FD_THIS dma_read((Bit8u *) &value); + BX_FD_THIS dma_read((Bit8u *) &value, 1); BX_FD_THIS lower_interrupt(); break; } else if (BX_FD_THIS s.command_complete) { @@ -1222,18 +1222,21 @@ void bx_floppy_ctrl_c::timer() } } -void bx_floppy_ctrl_c::dma_write(Bit8u *data_byte) +Bit16u bx_floppy_ctrl_c::dma_write(Bit8u *buffer, Bit16u maxlen) { // A DMA write is from I/O to Memory - // We need to return the next data byte from the floppy buffer + // We need to return the next data byte(s) from the floppy buffer // to be transfered via the DMA to memory. (read block from floppy) + // + // maxlen is the maximum length of the DMA transfer - Bit8u drive; + Bit8u drive = BX_FD_THIS s.DOR & 0x03; + Bit16u len = 512 - BX_FD_THIS s.floppy_buffer_index; + if (len > maxlen) len = maxlen; + memcpy(buffer, &BX_FD_THIS s.floppy_buffer[BX_FD_THIS s.floppy_buffer_index], len); + BX_FD_THIS s.floppy_buffer_index += len; + BX_FD_THIS s.TC = get_tc() && (len == maxlen); - drive = BX_FD_THIS s.DOR & 0x03; - *data_byte = BX_FD_THIS s.floppy_buffer[BX_FD_THIS s.floppy_buffer_index++]; - - BX_FD_THIS s.TC = get_tc(); if ((BX_FD_THIS s.floppy_buffer_index >= 512) || (BX_FD_THIS s.TC)) { if (BX_FD_THIS s.floppy_buffer_index >= 512) { @@ -1277,33 +1280,35 @@ void bx_floppy_ctrl_c::dma_write(Bit8u *data_byte) sector_time , 0); } } + return len; } -void bx_floppy_ctrl_c::dma_read(Bit8u *data_byte) +Bit16u bx_floppy_ctrl_c::dma_read(Bit8u *buffer, Bit16u maxlen) { // A DMA read is from Memory to I/O // We need to write the data_byte which was already transfered from memory // via DMA to I/O (write block to floppy) + // + // maxlen is the length of the DMA transfer (not implemented yet) - Bit8u drive; + Bit8u drive = BX_FD_THIS s.DOR & 0x03; Bit32u logical_sector, sector_time; - drive = BX_FD_THIS s.DOR & 0x03; if (BX_FD_THIS s.pending_command == 0x4d) { // format track in progress BX_FD_THIS s.format_count--; switch (3 - (BX_FD_THIS s.format_count & 0x03)) { case 0: - BX_FD_THIS s.cylinder[drive] = *data_byte; + BX_FD_THIS s.cylinder[drive] = *buffer; break; case 1: - if (*data_byte != BX_FD_THIS s.head[drive]) + if (*buffer != BX_FD_THIS s.head[drive]) BX_ERROR(("head number does not match head field")); break; case 2: - BX_FD_THIS s.sector[drive] = *data_byte; + BX_FD_THIS s.sector[drive] = *buffer; break; case 3: - if (*data_byte != 2) BX_ERROR(("dma_read: sector size %d not supported", 128<<(*data_byte))); + if (*buffer != 2) BX_ERROR(("dma_read: sector size %d not supported", 128<<(*buffer))); BX_DEBUG(("formatting cylinder %u head %u sector %u", BX_FD_THIS s.cylinder[drive], BX_FD_THIS s.head[drive], BX_FD_THIS s.sector[drive])); @@ -1324,10 +1329,14 @@ void bx_floppy_ctrl_c::dma_read(Bit8u *data_byte) sector_time , 0); break; } + return 1; } else { // write normal data - BX_FD_THIS s.floppy_buffer[BX_FD_THIS s.floppy_buffer_index++] = *data_byte; + Bit16u len = 512 - BX_FD_THIS s.floppy_buffer_index; + if (len > maxlen) len = maxlen; + memcpy(&BX_FD_THIS s.floppy_buffer[BX_FD_THIS s.floppy_buffer_index], buffer, len); + BX_FD_THIS s.floppy_buffer_index += len; + BX_FD_THIS s.TC = get_tc() && (len == maxlen); - BX_FD_THIS s.TC = get_tc(); if ((BX_FD_THIS s.floppy_buffer_index >= 512) || (BX_FD_THIS s.TC)) { logical_sector = (BX_FD_THIS s.cylinder[drive] * BX_FD_THIS s.media[drive].heads * BX_FD_THIS s.media[drive].sectors_per_track) + (BX_FD_THIS s.head[drive] * BX_FD_THIS s.media[drive].sectors_per_track) + @@ -1342,7 +1351,7 @@ void bx_floppy_ctrl_c::dma_read(Bit8u *data_byte) // ST2: CRCE=1, SERR=1, BCYL=1, NDAM=1. BX_FD_THIS s.status_reg2 = 0x31; // 0011 0001 enter_result_phase(); - return; + return 1; } floppy_xfer(drive, logical_sector*512, BX_FD_THIS s.floppy_buffer, 512, TO_FLOPPY); @@ -1360,6 +1369,7 @@ void bx_floppy_ctrl_c::dma_read(Bit8u *data_byte) enter_result_phase(); } } + return len; } } diff --git a/bochs/iodev/floppy.h b/bochs/iodev/floppy.h index 62108b4e2..feb54ead5 100644 --- a/bochs/iodev/floppy.h +++ b/bochs/iodev/floppy.h @@ -134,8 +134,8 @@ private: Bit32u read(Bit32u address, unsigned io_len); void write(Bit32u address, Bit32u value, unsigned io_len); #endif - BX_FD_SMF void dma_write(Bit8u *data_byte); - BX_FD_SMF void dma_read(Bit8u *data_byte); + BX_FD_SMF Bit16u dma_write(Bit8u *buffer, Bit16u maxlen); + BX_FD_SMF Bit16u dma_read(Bit8u *buffer, Bit16u maxlen); BX_FD_SMF void floppy_command(void); BX_FD_SMF void floppy_xfer(Bit8u drive, Bit32u offset, Bit8u *buffer, Bit32u bytes, Bit8u direction); BX_FD_SMF void raise_interrupt(void); diff --git a/bochs/iodev/iodev.h b/bochs/iodev/iodev.h index c7d652ce6..f6fbfe1a5 100644 --- a/bochs/iodev/iodev.h +++ b/bochs/iodev/iodev.h @@ -192,16 +192,16 @@ class BOCHSAPI bx_dma_stub_c : public bx_devmodel_c { public: virtual unsigned registerDMA8Channel( unsigned channel, - void (* dmaRead)(Bit8u *data_byte), - void (* dmaWrite)(Bit8u *data_byte), + Bit16u (* dmaRead)(Bit8u *data_byte, Bit16u maxlen), + Bit16u (* dmaWrite)(Bit8u *data_byte, Bit16u maxlen), const char *name) { STUBFUNC(dma, registerDMA8Channel); return 0; } virtual unsigned registerDMA16Channel( unsigned channel, - void (* dmaRead)(Bit16u *data_word), - void (* dmaWrite)(Bit16u *data_word), + Bit16u (* dmaRead)(Bit16u *data_word, Bit16u maxlen), + Bit16u (* dmaWrite)(Bit16u *data_word, Bit16u maxlen), const char *name) { STUBFUNC(dma, registerDMA16Channel); return 0; diff --git a/bochs/iodev/sound/sb16.cc b/bochs/iodev/sound/sb16.cc index 8e8174819..bb57b7207 100644 --- a/bochs/iodev/sound/sb16.cc +++ b/bochs/iodev/sound/sb16.cc @@ -1564,7 +1564,7 @@ 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) -void bx_sb16_c::dma_read8(Bit8u *data_byte) +Bit16u bx_sb16_c::dma_read8(Bit8u *data_byte, Bit16u maxlen) { DEV_dma_set_drq(BX_SB16_DMAL, 0); // the timer will raise it again @@ -1577,9 +1577,11 @@ void bx_sb16_c::dma_read8(Bit8u *data_byte) if (DSP.dma.count == 0xffff) // last byte received dsp_dmadone(); + + return 1; } -void bx_sb16_c::dma_write8(Bit8u *data_byte) +Bit16u bx_sb16_c::dma_write8(Bit8u *data_byte, Bit16u maxlen) { DEV_dma_set_drq(BX_SB16_DMAL, 0); // the timer will raise it again @@ -1593,9 +1595,11 @@ void bx_sb16_c::dma_write8(Bit8u *data_byte) if (DSP.dma.count == 0xffff) // last byte sent dsp_dmadone(); + + return 1; } -void bx_sb16_c::dma_read16(Bit16u *data_word) +Bit16u bx_sb16_c::dma_read16(Bit16u *data_word, Bit16u maxlen) { DEV_dma_set_drq(BX_SB16_DMAH, 0); // the timer will raise it again @@ -1610,9 +1614,11 @@ void bx_sb16_c::dma_read16(Bit16u *data_word) if (DSP.dma.count == 0xffff) // last word received dsp_dmadone(); + + return 1; } -void bx_sb16_c::dma_write16(Bit16u *data_word) +Bit16u bx_sb16_c::dma_write16(Bit16u *data_word, Bit16u maxlen) { Bit8u byte1, byte2; @@ -1632,6 +1638,8 @@ void bx_sb16_c::dma_write16(Bit16u *data_word) if (DSP.dma.count == 0xffff) // last word sent dsp_dmadone(); + + return 1; } // 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 595ac575b..32ca48eb7 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 void dma_write8(Bit8u *data_byte); - BX_SB16_SMF void dma_read8(Bit8u *data_byte); - BX_SB16_SMF void dma_write16(Bit16u *data_word); - BX_SB16_SMF void dma_read16(Bit16u *data_word); + 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); /* the MPU 401 part of the emulator */ BX_SB16_SMF Bit32u mpu_status(); // read status port 3x1 diff --git a/bochs/patches/patch.fast-dma-cbothamy b/bochs/patches/patch.fast-dma-cbothamy deleted file mode 100644 index ba74e3316..000000000 --- a/bochs/patches/patch.fast-dma-cbothamy +++ /dev/null @@ -1,572 +0,0 @@ ----------------------------------------------------------------------- -Patch name: patch.fast-dma-cbothamy -Author: Christophe Bothamy -Date: Wed Feb 18 14:00:40 CET 2004 -Status: Proposed changes - -Detailed description: -This patch improves DMA transfers by moving more than one byte -on each cpu tick. This works only on address-incrementing DMA -transfers. The number of transferred bytes is currently -limited to 512 on each cpu tick, but can be easily increased. -Only floppy DMA transfers are impacted right now, and DOS 6.2 -and Win95 seems to work fine with the patch applied. -The performance increase is (measured on a 1GHz PIII, with -all optimizations enabled) : - -command without patch with patch -format a: 4s 3s -surface scan of scandisk 17s 10s -xcopy a: b: 14s 4s - -These tests prefigures what kind of performance increase we -can get by implementing the IDE BusMaster feature. - -More test on more guest os are needed to find probable -incompatibilities. - -Todo: -- implement similar changes for sb16 -- fix BX_DBG_DMA_REPORT to report data from buffer - -Patch was created with: - cvs diff -u -Apply patch to what version: - cvs checked out on DATE, release version VER -Instructions: - To patch, go to main bochs directory. - Type "patch -p0 < THIS_PATCH_FILE". ----------------------------------------------------------------------- -Index: bochs.h -=================================================================== -RCS file: /cvsroot/bochs/bochs/bochs.h,v -retrieving revision 1.136 -diff -u -r1.136 bochs.h ---- bochs.h 6 Feb 2004 22:27:59 -0000 1.136 -+++ bochs.h 18 Feb 2004 13:41:55 -0000 -@@ -491,6 +491,8 @@ - #define BX_RW 2 - - -+#define BX_MEM_GET_HOST_MEM_ADDR_READ(addr) BX_MEM(0)->getHostMemAddr(NULL, addr, BX_READ) -+#define BX_MEM_GET_HOST_MEM_ADDR_WRITE(addr) BX_MEM(0)->getHostMemAddr(NULL, addr, BX_WRITE) - - - -Index: iodev/dma.cc -=================================================================== -RCS file: /cvsroot/bochs/bochs/iodev/dma.cc,v -retrieving revision 1.30 -diff -u -r1.30 dma.cc ---- iodev/dma.cc 31 Jul 2003 15:29:34 -0000 1.30 -+++ iodev/dma.cc 18 Feb 2004 13:41:59 -0000 -@@ -70,8 +70,8 @@ - unsigned - bx_dma_c::registerDMA8Channel( - unsigned channel, -- void (* dmaRead)(Bit8u *data_byte), -- void (* dmaWrite)(Bit8u *data_byte), -+ void (* dmaRead)(Bit8u *data_byte, Bit16u len), -+ void (* dmaWrite)(Bit8u *data_byte, Bit16u len), - const char *name - ) - { -@@ -93,8 +93,8 @@ - unsigned - bx_dma_c::registerDMA16Channel( - unsigned channel, -- void (* dmaRead)(Bit16u *data_word), -- void (* dmaWrite)(Bit16u *data_word), -+ void (* dmaRead)(Bit16u *data_word, Bit16u len), -+ void (* dmaWrite)(Bit16u *data_word, Bit16u len), - const char *name - ) - { -@@ -709,12 +709,26 @@ - (BX_DMA_THIS s[ma_sl].chan[channel].current_address << ma_sl); - - BX_DMA_THIS s[ma_sl].DACK[channel] = 1; -- // check for expiration of count, so we can signal TC and DACK(n) -- // at the same time. -- if (BX_DMA_THIS s[ma_sl].chan[channel].mode.address_decrement==0) -+ -+ Bit16u length; -+ if (BX_DMA_THIS s[ma_sl].chan[channel].mode.address_decrement==0) { -+ // Maxout length, it could be per device selectable -+ length=BX_DMA_THIS s[ma_sl].chan[channel].current_count; -+ if (length > 511) length=511; -+ -+ BX_DMA_THIS s[ma_sl].chan[channel].current_address+=length; - BX_DMA_THIS s[ma_sl].chan[channel].current_address++; -- else -+ } -+ else { -+ // When decrementing it is easier to do it 1 byte at a time -+ length=0; -+ //BX_DMA_THIS s[ma_sl].chan[channel].current_address-=length; - BX_DMA_THIS s[ma_sl].chan[channel].current_address--; -+ } -+ -+ // check for expiration of count, so we can signal TC and DACK(n) -+ // at the same time. -+ BX_DMA_THIS s[ma_sl].chan[channel].current_count-=length; - BX_DMA_THIS s[ma_sl].chan[channel].current_count--; - if (BX_DMA_THIS s[ma_sl].chan[channel].current_count == 0xffff) { - // count expired, done with transfer -@@ -736,65 +750,86 @@ - } - } - -- Bit8u data_byte; -- Bit16u data_word; -+ Bit8u *data8; -+ Bit16u *data16; - - if (BX_DMA_THIS s[ma_sl].chan[channel].mode.transfer_type == 1) { // write - // DMA controlled xfer of byte from I/O to Memory - - if (!ma_sl) { -- if (BX_DMA_THIS h[channel].dmaWrite8) -- BX_DMA_THIS h[channel].dmaWrite8(&data_byte); -- else -- BX_PANIC(("no dmaWrite handler for channel %u.", channel)); - -- BX_MEM_WRITE_PHYSICAL(phy_addr, 1, &data_byte); -+ data8 = BX_MEM_GET_HOST_MEM_ADDR_WRITE(phy_addr); -+ if (data8 == NULL) -+ BX_PANIC(("dma8 tries to write outside memory")); -+ else -+ if (BX_DMA_THIS h[channel].dmaWrite8) -+ BX_DMA_THIS h[channel].dmaWrite8(data8, length); -+ else -+ BX_PANIC(("no dmaWrite handler for channel %u.", channel)); - -- BX_DBG_DMA_REPORT(phy_addr, 1, BX_WRITE, data_byte); -+ //BX_MEM_WRITE_PHYSICAL(phy_addr, 1+(Bit32u)length, &data_byte); -+ -+ //BX_DBG_DMA_REPORT(phy_addr, 1, BX_WRITE, &data_byte); - } - else { -- if (BX_DMA_THIS h[channel].dmaWrite16) -- BX_DMA_THIS h[channel].dmaWrite16(&data_word); -+ -+ data16 = (Bit16u*)BX_MEM_GET_HOST_MEM_ADDR_WRITE(phy_addr); -+ if (data16 == NULL) -+ BX_PANIC(("dma16 tries to write outside memory")); - else -- BX_PANIC(("no dmaWrite handler for channel %u.", channel)); -+ if (BX_DMA_THIS h[channel].dmaWrite16) -+ BX_DMA_THIS h[channel].dmaWrite16(data16, length); -+ else -+ BX_PANIC(("no dmaWrite handler for channel %u.", channel)); - -- BX_MEM_WRITE_PHYSICAL(phy_addr, 2, &data_word); -+ //BX_MEM_WRITE_PHYSICAL(phy_addr, 2*(1+(Bit32u)length), data_word); - -- BX_DBG_DMA_REPORT(phy_addr, 2, BX_WRITE, data_word); -+ //BX_DBG_DMA_REPORT(phy_addr, 2, BX_WRITE, data_word); - } - } - 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 - - if (!ma_sl) { -- BX_MEM_READ_PHYSICAL(phy_addr, 1, &data_byte); -+ //BX_MEM_READ_PHYSICAL(phy_addr, 1+(Bit32u)length, &data_byte); - -- if (BX_DMA_THIS h[channel].dmaRead8) -- BX_DMA_THIS h[channel].dmaRead8(&data_byte); -+ data8 = BX_MEM_GET_HOST_MEM_ADDR_READ(phy_addr); -+ if (data8 == NULL) -+ BX_PANIC(("dma8 tries to read outside memory")); -+ else -+ if (BX_DMA_THIS h[channel].dmaRead8) -+ BX_DMA_THIS h[channel].dmaRead8(data8, length); - -- BX_DBG_DMA_REPORT(phy_addr, 1, BX_READ, data_byte); -+ //BX_DBG_DMA_REPORT(phy_addr, 1, BX_READ, &data_byte); - } - else { -- BX_MEM_READ_PHYSICAL(phy_addr, 2, &data_word); -+ // BX_MEM_READ_PHYSICAL(phy_addr, 2*(1+(Bit32u)length), data_word); - -- if (BX_DMA_THIS h[channel].dmaRead16) -- BX_DMA_THIS h[channel].dmaRead16(&data_word); -+ data16 = (Bit16u*)BX_MEM_GET_HOST_MEM_ADDR_WRITE(phy_addr); -+ if (data16 == NULL) -+ BX_PANIC(("dma16 tries to read outside memory")); -+ else -+ if (BX_DMA_THIS h[channel].dmaRead16) -+ BX_DMA_THIS h[channel].dmaRead16(data16,length); - -- BX_DBG_DMA_REPORT(phy_addr, 2, BX_READ, data_word); -+ //BX_DBG_DMA_REPORT(phy_addr, 2, BX_READ, data_word); - } - } - else if (BX_DMA_THIS s[ma_sl].chan[channel].mode.transfer_type == 0) { - // verify - -+ // Buffer for verify, max 64k words -+ Bit16u buffer[64*1024]; -+ - if (!ma_sl) { - if (BX_DMA_THIS h[channel].dmaWrite8) -- BX_DMA_THIS h[channel].dmaWrite8(&data_byte); -+ BX_DMA_THIS h[channel].dmaWrite8((Bit8u*)buffer, length); - else - BX_PANIC(("no dmaWrite handler for channel %u.", channel)); - } - else { - if (BX_DMA_THIS h[channel].dmaWrite16) -- BX_DMA_THIS h[channel].dmaWrite16(&data_word); -+ BX_DMA_THIS h[channel].dmaWrite16(buffer, length); - else - BX_PANIC(("no dmaWrite handler for channel %u.", channel)); - } -Index: iodev/dma.h -=================================================================== -RCS file: /cvsroot/bochs/bochs/iodev/dma.h,v -retrieving revision 1.15 -diff -u -r1.15 dma.h ---- iodev/dma.h 3 May 2003 07:41:27 -0000 1.15 -+++ iodev/dma.h 18 Feb 2004 13:41:59 -0000 -@@ -52,12 +52,12 @@ - virtual unsigned get_TC(void); - - virtual unsigned registerDMA8Channel(unsigned channel, -- void (* dmaRead)(Bit8u *data_byte), -- void (* dmaWrite)(Bit8u *data_byte), -+ void (* dmaRead)(Bit8u *data_byte, Bit16u len), -+ void (* dmaWrite)(Bit8u *data_byte, Bit16u len), - const char *name); - virtual unsigned registerDMA16Channel(unsigned channel, -- void (* dmaRead)(Bit16u *data_word), -- void (* dmaWrite)(Bit16u *data_word), -+ void (* dmaRead)(Bit16u *data_word, Bit16u len), -+ void (* dmaWrite)(Bit16u *data_word, Bit16u len), - const char *name); - virtual unsigned unregisterDMAChannel(unsigned channel); - -@@ -102,10 +102,10 @@ - bx_bool TC; // Terminal Count - - struct { -- void (* dmaRead8)(Bit8u *data_byte); -- void (* dmaWrite8)(Bit8u *data_byte); -- void (* dmaRead16)(Bit16u *data_word); -- void (* dmaWrite16)(Bit16u *data_word); -+ void (* dmaRead8)(Bit8u *data_byte, Bit16u len); -+ void (* dmaWrite8)(Bit8u *data_byte, Bit16u len); -+ void (* dmaRead16)(Bit16u *data_word, Bit16u len); -+ void (* dmaWrite16)(Bit16u *data_word, Bit16u len); - } h[4]; // DMA read and write handlers - - }; -Index: iodev/floppy.cc -=================================================================== -RCS file: /cvsroot/bochs/bochs/iodev/floppy.cc,v -retrieving revision 1.72 -diff -u -r1.72 floppy.cc ---- iodev/floppy.cc 8 Feb 2004 18:38:26 -0000 1.72 -+++ iodev/floppy.cc 18 Feb 2004 13:42:04 -0000 -@@ -1110,66 +1110,91 @@ - } - - void --bx_floppy_ctrl_c::dma_write(Bit8u *data_byte) -+bx_floppy_ctrl_c::dma_write(Bit8u *data_byte, Bit16u len) - { - // A DMA write is from I/O to Memory - // We need to return then next data byte from the floppy buffer - // to be transfered via the DMA to memory. (read block from floppy) -+ // -+ // len is the length of the DMA transfert minus 1 byte - -+ Bit32u xfer_len; -+ Bit8u drive = BX_FD_THIS s.DOR & 0x03; - -- *data_byte = BX_FD_THIS s.floppy_buffer[BX_FD_THIS s.floppy_buffer_index++]; -+ if ( BX_FD_THIS s.floppy_buffer_index >= 512) -+ BX_PANIC(("Index should not be >= 512")); - -- if (BX_FD_THIS s.floppy_buffer_index >= 512) { -- Bit8u drive; -+ do { -+ xfer_len = 512 - BX_FD_THIS s.floppy_buffer_index; -+ if (xfer_len > ((Bit32u)len + 1)) xfer_len = (Bit32u)len + 1; -+ if (xfer_len == 1) -+ *data_byte = BX_FD_THIS s.floppy_buffer[BX_FD_THIS s.floppy_buffer_index++]; -+ else { -+ memcpy(data_byte, &BX_FD_THIS s.floppy_buffer[BX_FD_THIS s.floppy_buffer_index],xfer_len); -+ BX_FD_THIS s.floppy_buffer_index += xfer_len; -+ } - -- drive = BX_FD_THIS s.DOR & 0x03; -- increment_sector(); // increment to next sector before retrieving next one -- BX_FD_THIS s.floppy_buffer_index = 0; -- if (DEV_dma_get_tc()) { // Terminal Count line, done -- BX_FD_THIS s.status_reg0 = (BX_FD_THIS s.head[drive] << 2) | drive; -- BX_FD_THIS s.status_reg1 = 0; -- BX_FD_THIS s.status_reg2 = 0; -+ data_byte += xfer_len; -+ len -= (Bit16u)xfer_len; - -- if (bx_dbg.floppy) { -- BX_INFO(("<>")); -- BX_INFO(("AFTER")); -- BX_INFO((" drive = %u", (unsigned) drive)); -- BX_INFO((" head = %u", (unsigned) BX_FD_THIS s.head[drive])); -- BX_INFO((" cylinder = %u", (unsigned) BX_FD_THIS s.cylinder[drive])); -- BX_INFO((" sector = %u", (unsigned) BX_FD_THIS s.sector[drive])); -- } -+ if (BX_FD_THIS s.floppy_buffer_index >= 512) { -+ increment_sector(); // increment to next sector before retrieving next one -+ BX_FD_THIS s.floppy_buffer_index = 0; -+ -+ // Only needed if more data to transfer -+ if (!DEV_dma_get_tc()) { -+ Bit32u logical_sector; -+ -+ // original assumed all floppies had two sides...now it does not *delete this comment line* -+ logical_sector = (BX_FD_THIS s.cylinder[drive] * BX_FD_THIS s.media[drive].heads * -+ BX_FD_THIS s.media[drive].sectors_per_track) + -+ (BX_FD_THIS s.head[drive] * -+ BX_FD_THIS s.media[drive].sectors_per_track) + -+ (BX_FD_THIS s.sector[drive] - 1); - -- DEV_dma_set_drq(FLOPPY_DMA_CHAN, 0); -- enter_result_phase(); -+ floppy_xfer(drive, logical_sector*512, BX_FD_THIS s.floppy_buffer, -+ 512, FROM_FLOPPY); -+ } - } -- else { // more data to transfer -- Bit32u logical_sector; -- -- // original assumed all floppies had two sides...now it does not *delete this comment line* -- logical_sector = (BX_FD_THIS s.cylinder[drive] * BX_FD_THIS s.media[drive].heads * -- BX_FD_THIS s.media[drive].sectors_per_track) + -- (BX_FD_THIS s.head[drive] * -- BX_FD_THIS s.media[drive].sectors_per_track) + -- (BX_FD_THIS s.sector[drive] - 1); -+ } while (len!=0xffff); -+ -+ // If DMA transfer is over -+ if (DEV_dma_get_tc()) { // Terminal Count line, done -+ BX_FD_THIS s.status_reg0 = (BX_FD_THIS s.head[drive] << 2) | drive; -+ BX_FD_THIS s.status_reg1 = 0; -+ BX_FD_THIS s.status_reg2 = 0; -+ -+ if (bx_dbg.floppy) { -+ BX_INFO(("<>")); -+ BX_INFO(("AFTER")); -+ BX_INFO((" drive = %u", (unsigned) drive)); -+ BX_INFO((" head = %u", (unsigned) BX_FD_THIS s.head[drive])); -+ BX_INFO((" cylinder = %u", (unsigned) BX_FD_THIS s.cylinder[drive])); -+ BX_INFO((" sector = %u", (unsigned) BX_FD_THIS s.sector[drive])); -+ } - -- floppy_xfer(drive, logical_sector*512, BX_FD_THIS s.floppy_buffer, -- 512, FROM_FLOPPY); -+ DEV_dma_set_drq(FLOPPY_DMA_CHAN, 0); -+ enter_result_phase(); - } -- } -+ return; - } - - void --bx_floppy_ctrl_c::dma_read(Bit8u *data_byte) -+bx_floppy_ctrl_c::dma_read(Bit8u *data_byte, Bit16u len) - { - // A DMA read is from Memory to I/O - // We need to write the data_byte which was already transfered from memory - // via DMA to I/O (write block to floppy) -+ // -+ // len is the length of the DMA transfert minus 1 byte - - Bit8u drive; - Bit32u logical_sector; - - drive = BX_FD_THIS s.DOR & 0x03; -+ - if (BX_FD_THIS s.pending_command == 0x4d) { // format track in progress -+ do { - --BX_FD_THIS s.format_count; - switch (3 - (BX_FD_THIS s.format_count & 0x03)) { - case 0: -@@ -1187,50 +1212,76 @@ - BX_DEBUG(("formatting cylinder %u head %u sector %u", - BX_FD_THIS s.cylinder[drive], BX_FD_THIS s.head[drive], - BX_FD_THIS s.sector[drive])); -- for (unsigned i = 0; i < 512; i++) { -- BX_FD_THIS s.floppy_buffer[i] = BX_FD_THIS s.format_fillbyte; -- } -+ memset(BX_FD_THIS s.floppy_buffer, BX_FD_THIS s.format_fillbyte, 512); - // original assumed all floppies had two sides...now it does not *delete this comment line* -- logical_sector = (BX_FD_THIS s.cylinder[drive] * BX_FD_THIS s.media[drive].heads * BX_FD_THIS s.media[drive].sectors_per_track) + -+ logical_sector = (BX_FD_THIS s.cylinder[drive] * BX_FD_THIS s.media[drive].heads * -+ BX_FD_THIS s.media[drive].sectors_per_track) + - (BX_FD_THIS s.head[drive] * BX_FD_THIS s.media[drive].sectors_per_track) + - (BX_FD_THIS s.sector[drive] - 1); - floppy_xfer(drive, logical_sector*512, BX_FD_THIS s.floppy_buffer, - 512, TO_FLOPPY); - break; - } -+ -+ len --; -+ data_byte++; -+ } while (len != 0xffff); -+ - if ((BX_FD_THIS s.format_count == 0) || (DEV_dma_get_tc())) { - BX_FD_THIS s.format_count = 0; - BX_FD_THIS s.status_reg0 = (BX_FD_THIS s.head[drive] << 2) | drive; - DEV_dma_set_drq(FLOPPY_DMA_CHAN, 0); - enter_result_phase(); - } -+ - return; - } -+ else { // format track not in progress -+ if ( BX_FD_THIS s.media[drive].write_protected ) { -+ // write protected error -+ BX_INFO(("tried to write disk %u, which is write-protected", drive)); -+ // ST0: IC1,0=01 (abnormal termination: started execution but failed) -+ BX_FD_THIS s.status_reg0 = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive; -+ // ST1: DataError=1, NDAT=1, NotWritable=1, NID=1 -+ BX_FD_THIS s.status_reg1 = 0x27; // 0010 0111 -+ // ST2: CRCE=1, SERR=1, BCYL=1, NDAM=1. -+ BX_FD_THIS s.status_reg2 = 0x31; // 0011 0001 -+ enter_result_phase(); -+ return; -+ } - -- BX_FD_THIS s.floppy_buffer[BX_FD_THIS s.floppy_buffer_index++] = *data_byte; -+ Bit32u xfer_len; - -- if (BX_FD_THIS s.floppy_buffer_index >= 512) { -- // original assumed all floppies had two sides...now it does not *delete this comment line* -- logical_sector = (BX_FD_THIS s.cylinder[drive] * BX_FD_THIS s.media[drive].heads * BX_FD_THIS s.media[drive].sectors_per_track) + -- (BX_FD_THIS s.head[drive] * BX_FD_THIS s.media[drive].sectors_per_track) + -- (BX_FD_THIS s.sector[drive] - 1); -- if ( BX_FD_THIS s.media[drive].write_protected ) { -- // write protected error -- BX_INFO(("tried to write disk %u, which is write-protected", drive)); -- // ST0: IC1,0=01 (abnormal termination: started execution but failed) -- BX_FD_THIS s.status_reg0 = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive; -- // ST1: DataError=1, NDAT=1, NotWritable=1, NID=1 -- BX_FD_THIS s.status_reg1 = 0x27; // 0010 0111 -- // ST2: CRCE=1, SERR=1, BCYL=1, NDAM=1. -- BX_FD_THIS s.status_reg2 = 0x31; // 0011 0001 -- enter_result_phase(); -- return; -+ if ( BX_FD_THIS s.floppy_buffer_index >= 512) -+ BX_PANIC(("Index should not be >= 512")); -+ -+ do { -+ -+ xfer_len = 512 - BX_FD_THIS s.floppy_buffer_index; -+ if (xfer_len > ((Bit32u)len + 1)) xfer_len = (Bit32u)len + 1; -+ if (xfer_len == 1) -+ BX_FD_THIS s.floppy_buffer[BX_FD_THIS s.floppy_buffer_index++] = *data_byte; -+ else { -+ memcpy(&BX_FD_THIS s.floppy_buffer[BX_FD_THIS s.floppy_buffer_index],data_byte,xfer_len); -+ BX_FD_THIS s.floppy_buffer_index += xfer_len; - } -- floppy_xfer(drive, logical_sector*512, BX_FD_THIS s.floppy_buffer, -+ -+ data_byte += xfer_len; -+ len -= (Bit16u)xfer_len; -+ -+ if (BX_FD_THIS s.floppy_buffer_index >= 512) { -+ // original assumed all floppies had two sides...now it does not *delete this comment line* -+ logical_sector = (BX_FD_THIS s.cylinder[drive] * BX_FD_THIS s.media[drive].heads * BX_FD_THIS s.media[drive].sectors_per_track) + -+ (BX_FD_THIS s.head[drive] * BX_FD_THIS s.media[drive].sectors_per_track) + -+ (BX_FD_THIS s.sector[drive] - 1); -+ floppy_xfer(drive, logical_sector*512, BX_FD_THIS s.floppy_buffer, - 512, TO_FLOPPY); -- increment_sector(); // increment to next sector after writing current one -- BX_FD_THIS s.floppy_buffer_index = 0; -- if (DEV_dma_get_tc()) { // Terminal Count line, done -+ increment_sector(); // increment to next sector after writing current one -+ BX_FD_THIS s.floppy_buffer_index = 0; -+ } // if BX_FD_THIS s.floppy_buffer_index >= 512 -+ } while (len != 0xffff); -+ -+ if (DEV_dma_get_tc()) { // Terminal Count line, done - BX_FD_THIS s.status_reg0 = (BX_FD_THIS s.head[drive] << 2) | drive; - BX_FD_THIS s.status_reg1 = 0; - BX_FD_THIS s.status_reg2 = 0; -@@ -1243,13 +1294,11 @@ - BX_INFO((" cylinder = %u", (unsigned) BX_FD_THIS s.cylinder[drive])); - BX_INFO((" sector = %u", (unsigned) BX_FD_THIS s.sector[drive])); - } -- -+ - DEV_dma_set_drq(FLOPPY_DMA_CHAN, 0); - enter_result_phase(); -- } -- else { // more data to transfer -- } // else -- } // if BX_FD_THIS s.floppy_buffer_index >= 512 -+ } -+ } - } - - void -@@ -1286,8 +1335,8 @@ - if (BX_FD_THIS s.cylinder[drive] >= BX_FD_THIS s.media[drive].tracks) { - // Set to 1 past last possible cylinder value. - // I notice if I set it to tracks-1, prama linux won't boot. -+ BX_INFO(("increment_sector: clamping cylinder %x to max",BX_FD_THIS s.cylinder[drive])); - BX_FD_THIS s.cylinder[drive] = BX_FD_THIS s.media[drive].tracks; -- BX_INFO(("increment_sector: clamping cylinder to max")); - } - } - } -Index: iodev/floppy.h -=================================================================== -RCS file: /cvsroot/bochs/bochs/iodev/floppy.h,v -retrieving revision 1.17 -diff -u -r1.17 floppy.h ---- iodev/floppy.h 7 Feb 2004 14:34:34 -0000 1.17 -+++ iodev/floppy.h 18 Feb 2004 13:42:04 -0000 -@@ -123,8 +123,8 @@ - Bit32u read(Bit32u address, unsigned io_len); - void write(Bit32u address, Bit32u value, unsigned io_len); - #endif -- BX_FD_SMF void dma_write(Bit8u *data_byte); -- BX_FD_SMF void dma_read(Bit8u *data_byte); -+ BX_FD_SMF void dma_write(Bit8u *data_byte, Bit16u len); -+ BX_FD_SMF void dma_read(Bit8u *data_byte, Bit16u len); - BX_FD_SMF void floppy_command(void); - BX_FD_SMF void floppy_xfer(Bit8u drive, Bit32u offset, Bit8u *buffer, Bit32u bytes, Bit8u direction); - BX_FD_SMF void raise_interrupt(void); -Index: iodev/iodev.h -=================================================================== -RCS file: /cvsroot/bochs/bochs/iodev/iodev.h,v -retrieving revision 1.41 -diff -u -r1.41 iodev.h ---- iodev/iodev.h 2 Feb 2004 21:47:26 -0000 1.41 -+++ iodev/iodev.h 18 Feb 2004 13:42:05 -0000 -@@ -176,16 +176,16 @@ - public: - virtual unsigned registerDMA8Channel( - unsigned channel, -- void (* dmaRead)(Bit8u *data_byte), -- void (* dmaWrite)(Bit8u *data_byte), -+ void (* dmaRead)(Bit8u *data_byte, Bit16u len), -+ void (* dmaWrite)(Bit8u *data_byte, Bit16u len), - const char *name - ) { - STUBFUNC(dma, registerDMA8Channel); return 0; - } - virtual unsigned registerDMA16Channel( - unsigned channel, -- void (* dmaRead)(Bit16u *data_word), -- void (* dmaWrite)(Bit16u *data_word), -+ void (* dmaRead)(Bit16u *data_word, Bit16u len), -+ void (* dmaWrite)(Bit16u *data_word, Bit16u len), - const char *name - ) { - STUBFUNC(dma, registerDMA16Channel); return 0;