1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-05 10:28:58 +00:00

Starts work on the DMA controller.

This commit is contained in:
Thomas Harte 2019-10-26 21:33:57 -04:00
parent ecc0cea5a1
commit ac39fd0235
4 changed files with 154 additions and 6 deletions

View File

@ -17,7 +17,9 @@
#include "../../Components/68901/MFP68901.hpp"
#include "../../Components/6850/6850.hpp"
#include "DMAController.hpp"
#include "Video.hpp"
#include "../../ClockReceiver/JustInTime.hpp"
#include "../../ClockReceiver/ForceInline.hpp"
@ -507,13 +509,23 @@ class ConcreteMachine:
// DMA.
case 0x7fc302: case 0x7fc303: case 0x7fc304: case 0x7fc305: case 0x7fc306:
if(!cycle.data_select_active()) return HalfCycles(0);
if(cycle.operation & Microcycle::Read) {
const uint8_t value = 0;
if(cycle.operation & Microcycle::SelectByte) {
cycle.value->halves.low = value;
const auto value = dma_->read(int(address));
if(cycle.operation & Microcycle::SelectWord) {
cycle.value->full = value;
} else {
cycle.value->halves.high = value;
cycle.value->halves.low = 0xff;
cycle.value->halves.low = uint8_t(value >> cycle.byte_shift());
}
} else {
if(cycle.operation & Microcycle::SelectWord) {
dma_->write(int(address), cycle.value->full);
} else {
dma_->write(int(address), uint16_t(
(cycle.value->halves.low << cycle.byte_shift()) |
(0xff00 >> cycle.byte_shift())
));
}
}
break;
@ -555,6 +567,7 @@ class ConcreteMachine:
forceinline void advance_time(HalfCycles length) {
cycles_since_audio_update_ += length;
mfp_ += length;
dma_ += length;
keyboard_acia_ += length;
midi_acia_ += length;
@ -597,6 +610,8 @@ class ConcreteMachine:
Outputs::Speaker::LowpassSpeaker<GI::AY38910::AY38910> speaker_;
HalfCycles cycles_since_audio_update_;
JustInTimeActor<DMAController> dma_;
HalfCycles cycles_since_ikbd_update_;
IntelligentKeyboard ikbd_;

View File

@ -0,0 +1,85 @@
//
// DMAController.cpp
// Clock Signal
//
// Created by Thomas Harte on 26/10/2019.
// Copyright © 2019 Thomas Harte. All rights reserved.
//
#include "DMAController.hpp"
#include <cstdio>
using namespace Atari::ST;
DMAController::DMAController() : fdc_(WD::WD1770::P1772) {
}
uint16_t DMAController::read(int address) {
switch(address & 7) {
// Reserved.
default: break;
// Disk controller or sector count.
case 2:
if(control_ & 0x10) {
return sector_count_;
} else {
return fdc_.get_register(control_ >> 1);
}
break;
// DMA status.
case 3:
return status_;
// DMA addressing.
case 4:
case 5:
case 6:
break;
}
return 0xffff;
}
void DMAController::write(int address, uint16_t value) {
switch(address & 7) {
// Reserved.
default: break;
// Disk controller or sector count.
case 2:
if(control_ & 0x10) {
sector_count_ = value;
} else {
fdc_.set_register(control_ >> 1, uint8_t(value));
}
break;
// DMA control; meaning is:
//
// b1, b2 = address lines for FDC access.
// b3 = 1 => HDC access; 0 => FDC access.
// b4 = 1 => sector count access; 1 => FDC access.
// b6 = 1 => DMA off; 0 => DMA on.
// b7 = 1 => FDC access; 0 => HDC access.
// b8 = 1 => write to [F/H]DC registers; 0 => read.
//
// All other bits: undefined.
// TODO: determine how b3 and b7 differ.
case 3:
control_ = value;
break;
// DMA addressing.
case 4:
case 5:
case 6:
break;
}
}
void DMAController::run_for(HalfCycles duration) {
running_time_ += duration;
fdc_.run_for(duration.flush<Cycles>());
}

View File

@ -0,0 +1,40 @@
//
// DMAController.hpp
// Clock Signal
//
// Created by Thomas Harte on 26/10/2019.
// Copyright © 2019 Thomas Harte. All rights reserved.
//
#ifndef DMAController_hpp
#define DMAController_hpp
#include <cstdint>
#include "../../ClockReceiver/ClockReceiver.hpp"
#include "../../Components/1770/1770.hpp"
namespace Atari {
namespace ST {
class DMAController {
public:
DMAController();
uint16_t read(int address);
void write(int address, uint16_t value);
void run_for(HalfCycles duration);
private:
HalfCycles running_time_;
WD::WD1770 fdc_;
uint16_t control_ = 0;
uint32_t address_ = 0;
uint16_t status_ = 0;
uint16_t sector_count_ = 0;
};
}
}
#endif /* DMAController_hpp */

View File

@ -142,6 +142,8 @@
4B1D08061E0F7A1100763741 /* TimeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B1D08051E0F7A1100763741 /* TimeTests.mm */; };
4B1E85811D176468001EF87D /* 6532Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1E85801D176468001EF87D /* 6532Tests.swift */; };
4B1EDB451E39A0AC009D6819 /* chip.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B1EDB431E39A0AC009D6819 /* chip.png */; };
4B21922D236523CB007FEEBC /* DMAController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B21922B236523CB007FEEBC /* DMAController.cpp */; };
4B21922E236523CB007FEEBC /* DMAController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B21922B236523CB007FEEBC /* DMAController.cpp */; };
4B2A332D1DB86821002876E3 /* OricOptions.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B2A332B1DB86821002876E3 /* OricOptions.xib */; };
4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A53911D117D36003C6002 /* CSAudioQueue.m */; };
4B2B3A4B1F9B8FA70062DABF /* Typer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3A471F9B8FA70062DABF /* Typer.cpp */; };
@ -829,6 +831,8 @@
4B1E857B1D174DEC001EF87D /* 6532.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = 6532.hpp; sourceTree = "<group>"; };
4B1E85801D176468001EF87D /* 6532Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 6532Tests.swift; sourceTree = "<group>"; };
4B1EDB431E39A0AC009D6819 /* chip.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chip.png; sourceTree = "<group>"; };
4B21922B236523CB007FEEBC /* DMAController.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DMAController.cpp; sourceTree = "<group>"; };
4B21922C236523CB007FEEBC /* DMAController.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DMAController.hpp; sourceTree = "<group>"; };
4B24095A1C45DF85004DA684 /* Stepper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Stepper.hpp; sourceTree = "<group>"; };
4B2A332C1DB86821002876E3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/OricOptions.xib"; sourceTree = SOURCE_ROOT; };
4B2A53901D117D36003C6002 /* CSAudioQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSAudioQueue.h; sourceTree = "<group>"; };
@ -3233,8 +3237,10 @@
isa = PBXGroup;
children = (
4BC131682346C61100E4FF3D /* AtariST.cpp */,
4BC131692346C61100E4FF3D /* AtariST.hpp */,
4B21922B236523CB007FEEBC /* DMAController.cpp */,
4BB50DC6234828A20057B9CA /* Video.cpp */,
4BC131692346C61100E4FF3D /* AtariST.hpp */,
4B21922C236523CB007FEEBC /* DMAController.hpp */,
4BB50DC7234828A20057B9CA /* Video.hpp */,
);
path = AtariST;
@ -4090,6 +4096,7 @@
4B055AB61FAE860F0060FFFF /* TapeUEF.cpp in Sources */,
4B055A9D1FAE85DA0060FFFF /* D64.cpp in Sources */,
4B055ABB1FAE86170060FFFF /* Oric.cpp in Sources */,
4B21922E236523CB007FEEBC /* DMAController.cpp in Sources */,
4B12C0EE1FCFAD1A005BFD93 /* Keyboard.cpp in Sources */,
4BCD634A22D6756400F567F1 /* MacintoshDoubleDensityDrive.cpp in Sources */,
4B05401F219D1618001BF69C /* ScanTarget.cpp in Sources */,
@ -4351,6 +4358,7 @@
4B1497881EE4A1DA00CE2596 /* ZX80O81P.cpp in Sources */,
4B894520201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
4BB4BFAD22A33DE50069048D /* DriveSpeedAccumulator.cpp in Sources */,
4B21922D236523CB007FEEBC /* DMAController.cpp in Sources */,
4B2B3A4B1F9B8FA70062DABF /* Typer.cpp in Sources */,
4B4518821F75E91A00926311 /* PCMSegment.cpp in Sources */,
4B74CF812312FA9C00500CE8 /* HFV.cpp in Sources */,