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:
parent
ad9e0b664a
commit
c31ee968df
@ -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 */
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user