diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index 80608ac1..d90ef803 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -32,12 +32,6 @@ #include "dma.h" #include "pic.h" -#if DEBUG_DMA -#define DMA_DEBUG LOG_DEBUG -#else -#define DMA_DEBUG -#endif - #define DMA_MODE_DEMAND 0 #define DMA_MODE_SINGLE 1 #define DMA_MODE_BLOCK 2 @@ -71,7 +65,9 @@ struct DMA_CONTROLLER { }; static DMA_CONTROLLER dma[2]; -void DMA_TestChannel(DMA_CHANNEL * chan); + +void DMA_CheckEnabled(DMA_CHANNEL * chan); +void DMA_SetEnabled(DMA_CHANNEL * chan,bool enabled); static Bit8u read_dma(Bit32u port) { /* only use first dma for now */ @@ -107,10 +103,10 @@ static Bit8u read_dma(Bit32u port) { default: LOG(LOG_DMA,LOG_ERROR)("DMA:Unhandled read from %X",port); } +// LOG_MSG("DMA Read port %x result %x",port,ret); return ret; } - static void write_dma(Bit32u port,Bit8u val) { /* only use first dma for now */ DMA_CONTROLLER * cont=&dma[0]; @@ -123,7 +119,6 @@ static void write_dma(Bit32u port,Bit8u val) { } else { chan->base_address=(chan->base_address & 0x00ff) | (val<<8); } -// LOG_MSG("DMA:Address %X",chan->base_address); cont->flipflop=!cont->flipflop; chan->addr_changed=true; break; @@ -134,10 +129,9 @@ static void write_dma(Bit32u port,Bit8u val) { } else { chan->base_count=(chan->base_count & 0x00ff) | (val<<8); } -// LOG_MSG("DMA:count %X",chan->base_count); cont->flipflop=!cont->flipflop; chan->addr_changed=true; - DMA_TestChannel(chan); + DMA_CheckEnabled(chan); break; case 0x08: /* Command Register */ if (val != 4) LOG(LOG_DMA,LOG_ERROR)("DMA1:Illegal command %2X",val); @@ -155,8 +149,13 @@ static void write_dma(Bit32u port,Bit8u val) { break; case 0x0a: /* single mask bit register */ chan=&cont->chan[val & 0x3]; - chan->masked=(val & 4)>0; - DMA_TestChannel(chan); + if ((val & 4)>0) { + DMA_SetEnabled(chan,false); + chan->masked=(val & 4)>0; //Set it later + } else { + chan->masked=(val & 4)>0; + DMA_CheckEnabled(chan); + } break; case 0x0b: /* mode register */ chan=&cont->chan[val & 0x3]; @@ -167,7 +166,7 @@ static void write_dma(Bit32u port,Bit8u val) { if (chan->mode.address_decrement) { LOG(LOG_DMA,LOG_ERROR)("DMA:Address Decrease not supported yet"); } - DMA_TestChannel(chan); + DMA_CheckEnabled(chan); break; case 0x0c: /* Clear Flip/Flip */ cont->flipflop=true; @@ -177,7 +176,6 @@ static void write_dma(Bit32u port,Bit8u val) { }; }; - void write_dma_page(Bit32u port,Bit8u val) { Bitu channel; switch (port) { @@ -194,20 +192,33 @@ void write_dma_page(Bit32u port,Bit8u val) { dma[0].chan[channel].addr_changed=true; } +Bit8u read_dma_page(Bit32u port) { + Bitu channel; + switch (port) { + case 0x81: /* dma0 page register, channel 2 */ + channel=2;break; + case 0x82: /* dma0 page register, channel 3 */ + channel=3;break; + case 0x83: /* dma0 page register, channel 1 */ + channel=1;break; + case 0x87: /* dma0 page register, channel 0 */ + channel=0;break; + } + return dma[0].chan[channel].page; +} INLINE void ResetDMA8(DMA_CHANNEL * chan) { chan->addr_changed=false; chan->address=(chan->page << 16)+chan->base_address; chan->current_count=chan->base_count+1; chan->current_address=chan->base_address; -// LOG_MSG("DMA8:Setup at address %X:%X count %X",chan->page<<12,chan->base_address,chan->current_count); + LOG(LOG_DMA,LOG_NORMAL)("Setup at address %X:%X count %X",chan->page<<12,chan->base_address,chan->current_count); } - - Bitu DMA_8_Read(Bitu dmachan,Bit8u * buffer,Bitu count) { DMA_CHANNEL * chan=&dma[0].chan[dmachan]; - if (chan->masked || !count) return 0; + if (chan->masked) return 0; + if (!count) return 0; if (chan->addr_changed) ResetDMA8(chan); if (chan->current_count>count) { MEM_BlockRead(chan->address,buffer,count); @@ -222,10 +233,10 @@ Bitu DMA_8_Read(Bitu dmachan,Bit8u * buffer,Bitu count) { /* Set the end of counter bit */ dma[0].status_reg|=(1 << dmachan); count=chan->current_count; - chan->current_address+=count;; + chan->address+=count; chan->current_count=0; - if (chan->enable_callback) chan->enable_callback(false); chan->enabled=false; + LOG(LOG_DMA,LOG_NORMAL)("8-bit Channel %d reached terminal count"); return count; } else { buffer+=chan->current_count; @@ -244,7 +255,8 @@ Bitu DMA_8_Read(Bitu dmachan,Bit8u * buffer,Bitu count) { Bitu DMA_8_Write(Bitu dmachan,Bit8u * buffer,Bitu count) { DMA_CHANNEL * chan=&dma[0].chan[dmachan]; - if (chan->masked || !count) return 0; + if (chan->masked) return 0; + if (!count) return 0; if (chan->addr_changed) ResetDMA8(chan); if (chan->current_count>count) { MEM_BlockWrite(chan->address,buffer,count); @@ -261,6 +273,7 @@ Bitu DMA_8_Write(Bitu dmachan,Bit8u * buffer,Bitu count) { count=chan->current_count; chan->current_address+=count;; chan->current_count=0; + chan->enabled=false; return count; } else { buffer+=chan->current_count; @@ -289,8 +302,13 @@ Bitu DMA_16_Write(Bitu dmachan,Bit8u * buffer,Bitu count) { return 0; } -void DMA_TestChannel(DMA_CHANNEL * chan) { - if (!chan->enable_callback) return; +void DMA_SetEnabled(DMA_CHANNEL * chan,bool enabled) { + if (chan->enabled == enabled) return; + chan->enabled=enabled; + if (chan->enable_callback) (*chan->enable_callback)(enabled); +} + +void DMA_CheckEnabled(DMA_CHANNEL * chan) { bool enabled; if (chan->masked) enabled=false; else { @@ -298,10 +316,7 @@ void DMA_TestChannel(DMA_CHANNEL * chan) { else if (chan->current_count || chan->addr_changed) enabled=true; else enabled=false; } - if (enabled == chan->enabled) return; - chan->enabled=enabled; - chan->enable_callback(enabled); - + DMA_SetEnabled(chan,enabled); } @@ -314,7 +329,7 @@ void DMA_SetEnableCallBack(Bitu channel,DMA_EnableCallBack callback) { } else return; chan->enabled=false; chan->enable_callback=callback; - DMA_TestChannel(chan); + DMA_CheckEnabled(chan); } void DMA_Init(Section* sec) { @@ -327,4 +342,10 @@ void DMA_Init(Section* sec) { IO_RegisterWriteHandler(0x82,write_dma_page,"DMA Pages"); IO_RegisterWriteHandler(0x83,write_dma_page,"DMA Pages"); IO_RegisterWriteHandler(0x87,write_dma_page,"DMA Pages"); + + IO_RegisterReadHandler(0x81,read_dma_page,"DMA Pages"); + IO_RegisterReadHandler(0x82,read_dma_page,"DMA Pages"); + IO_RegisterReadHandler(0x83,read_dma_page,"DMA Pages"); + IO_RegisterReadHandler(0x87,read_dma_page,"DMA Pages"); + }