1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 08:49:37 +00:00

TC: start tending towards meaning.

This commit is contained in:
Thomas Harte 2023-12-02 15:24:47 -05:00
parent ad9e0b664a
commit c31ee968df
2 changed files with 47 additions and 28 deletions

View File

@ -11,31 +11,41 @@
#include "../../Numeric/RegisterSizes.hpp" #include "../../Numeric/RegisterSizes.hpp"
#include "Memory.hpp"
namespace PCCompatible { namespace PCCompatible {
class i8237 { class i8237 {
public: public:
void flip_flop_reset() { void flip_flop_reset() {
printf("DMA: Flip flop reset\n");
next_access_low_ = true; next_access_low_ = true;
} }
void mask_reset() { void mask_reset() {
printf("DMA: Mask reset\n");
for(auto &channel : channels_) { for(auto &channel : channels_) {
channel.mask = false; channel.mask = false;
} }
} }
void master_reset() { void master_reset() {
printf("DMA: Master reset\n");
flip_flop_reset(); flip_flop_reset();
for(auto &channel : channels_) { for(auto &channel : channels_) {
channel.mask = true; channel.mask = true;
channel.transfer_complete = true; channel.transfer_complete = false;
channel.request = 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 <int address> template <int address>
void write(uint8_t value) { void write(uint8_t value) {
printf("DMA: Write %02x to %d\n", value, address);
constexpr int channel = (address >> 1) & 3; constexpr int channel = (address >> 1) & 3;
constexpr bool is_count = address & 1; constexpr bool is_count = address & 1;
@ -57,6 +67,7 @@ class i8237 {
template <int address> template <int address>
uint8_t read() { uint8_t read() {
printf("DMA: Read %d\n", address);
constexpr int channel = (address >> 1) & 3; constexpr int channel = (address >> 1) & 3;
constexpr bool is_count = address & 1; constexpr bool is_count = address & 1;
@ -77,14 +88,17 @@ class i8237 {
} }
void set_reset_mask(uint8_t value) { void set_reset_mask(uint8_t value) {
printf("DMA: Set/reset mask %02x\n", value);
channels_[value & 3].mask = value & 4; channels_[value & 3].mask = value & 4;
} }
void set_reset_request(uint8_t value) { void set_reset_request(uint8_t value) {
printf("DMA: Set/reset request %02x\n", value);
channels_[value & 3].request = value & 4; channels_[value & 3].request = value & 4;
} }
void set_mask(uint8_t value) { void set_mask(uint8_t value) {
printf("DMA: Set mask %02x\n", value);
channels_[0].mask = value & 1; channels_[0].mask = value & 1;
channels_[1].mask = value & 2; channels_[1].mask = value & 2;
channels_[2].mask = value & 4; channels_[2].mask = value & 4;
@ -92,6 +106,7 @@ class i8237 {
} }
void set_mode(uint8_t value) { 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].transfer = Channel::Transfer((value >> 2) & 3);
channels_[value & 3].autoinitialise = value & 0x10; channels_[value & 3].autoinitialise = value & 0x10;
channels_[value & 3].address_decrement = value & 0x20; channels_[value & 3].address_decrement = value & 0x20;
@ -99,6 +114,7 @@ class i8237 {
} }
void set_command(uint8_t value) { void set_command(uint8_t value) {
printf("DMA: Set command %02x\n", value);
enable_memory_to_memory_ = value & 0x01; enable_memory_to_memory_ = value & 0x01;
enable_channel0_address_hold_ = value & 0x02; enable_channel0_address_hold_ = value & 0x02;
enable_controller_ = value & 0x04; enable_controller_ = value & 0x04;
@ -124,6 +140,9 @@ class i8237 {
for(auto &channel : channels_) { for(auto &channel : channels_) {
channel.transfer_complete = false; channel.transfer_complete = false;
} }
printf("DMA: status is %02x\n", result);
return 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 */ #endif /* DMA_hpp */

View File

@ -49,33 +49,6 @@ namespace PCCompatible {
//bool log = false; //bool log = false;
//std::string previous; //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 { class FloppyController {
public: public:
FloppyController(PIC &pic, DMA &dma) : pic_(pic), dma_(dma) { FloppyController(PIC &pic, DMA &dma) : pic_(pic), dma_(dma) {