diff --git a/Machines/PCCompatible/DMA.hpp b/Machines/PCCompatible/DMA.hpp index 3e9795bbc..670286457 100644 --- a/Machines/PCCompatible/DMA.hpp +++ b/Machines/PCCompatible/DMA.hpp @@ -11,31 +11,41 @@ #include "../../Numeric/RegisterSizes.hpp" +#include "Memory.hpp" + namespace PCCompatible { class i8237 { public: void flip_flop_reset() { + printf("DMA: Flip flop reset\n"); next_access_low_ = true; } void mask_reset() { + printf("DMA: Mask reset\n"); for(auto &channel : channels_) { channel.mask = false; } } void master_reset() { + printf("DMA: Master reset\n"); flip_flop_reset(); for(auto &channel : channels_) { channel.mask = true; - channel.transfer_complete = true; + channel.transfer_complete = false; channel.request = false; } + + // This is a bit of a hack; DMA channel 0 is supposed to be linked to the PIT, + // performing DRAM refresh. It isn't yet. So hack this, and hack that. + channels_[0].transfer_complete = true; } template void write(uint8_t value) { + printf("DMA: Write %02x to %d\n", value, address); constexpr int channel = (address >> 1) & 3; constexpr bool is_count = address & 1; @@ -57,6 +67,7 @@ class i8237 { template uint8_t read() { + printf("DMA: Read %d\n", address); constexpr int channel = (address >> 1) & 3; constexpr bool is_count = address & 1; @@ -77,14 +88,17 @@ class i8237 { } void set_reset_mask(uint8_t value) { + printf("DMA: Set/reset mask %02x\n", value); channels_[value & 3].mask = value & 4; } void set_reset_request(uint8_t value) { + printf("DMA: Set/reset request %02x\n", value); channels_[value & 3].request = value & 4; } void set_mask(uint8_t value) { + printf("DMA: Set mask %02x\n", value); channels_[0].mask = value & 1; channels_[1].mask = value & 2; channels_[2].mask = value & 4; @@ -92,6 +106,7 @@ class i8237 { } void set_mode(uint8_t value) { + printf("DMA: Set mode %02x\n", value); channels_[value & 3].transfer = Channel::Transfer((value >> 2) & 3); channels_[value & 3].autoinitialise = value & 0x10; channels_[value & 3].address_decrement = value & 0x20; @@ -99,6 +114,7 @@ class i8237 { } void set_command(uint8_t value) { + printf("DMA: Set command %02x\n", value); enable_memory_to_memory_ = value & 0x01; enable_channel0_address_hold_ = value & 0x02; enable_controller_ = value & 0x04; @@ -124,6 +140,9 @@ class i8237 { for(auto &channel : channels_) { channel.transfer_complete = false; } + + printf("DMA: status is %02x\n", result); + return result; } @@ -227,6 +246,33 @@ class DMAPages { } }; +class DMA { + public: + i8237 controller; + DMAPages pages; + + // Memory is set posthoc to resolve a startup time. + void set_memory(Memory *memory) { + memory_ = memory; + } + + // TODO: this permits only 8-bit DMA. Fix that. + bool write(size_t channel, uint8_t value) { + auto address = controller.access(channel, true); + if(address == i8237::NotAvailable) { + return false; + } + + address |= uint32_t(pages.channel_page(channel) << 16); + *memory_->at(address) = value; + + return true; + } + + private: + Memory *memory_; +}; + } #endif /* DMA_hpp */ diff --git a/Machines/PCCompatible/PCCompatible.cpp b/Machines/PCCompatible/PCCompatible.cpp index f72314c63..d05701f7d 100644 --- a/Machines/PCCompatible/PCCompatible.cpp +++ b/Machines/PCCompatible/PCCompatible.cpp @@ -49,33 +49,6 @@ namespace PCCompatible { //bool log = false; //std::string previous; -class DMA { - public: - i8237 controller; - DMAPages pages; - - // Memory is set posthoc to resolve a startup time. - void set_memory(Memory *memory) { - memory_ = memory; - } - - // TODO: this permits only 8-bit DMA. Fix that. - bool write(size_t channel, uint8_t value) { - auto address = controller.access(channel, true); - if(address == i8237::NotAvailable) { - return false; - } - - address |= uint32_t(pages.channel_page(channel) << 16); - *memory_->at(address) = value; - - return true; - } - - private: - Memory *memory_; -}; - class FloppyController { public: FloppyController(PIC &pic, DMA &dma) : pic_(pic), dma_(dma) {