From ac39fd0235ba81eba9815ee694dec5cd21e6d74a Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 26 Oct 2019 21:33:57 -0400 Subject: [PATCH] Starts work on the DMA controller. --- Machines/AtariST/AtariST.cpp | 25 ++++-- Machines/AtariST/DMAController.cpp | 85 +++++++++++++++++++ Machines/AtariST/DMAController.hpp | 40 +++++++++ .../Clock Signal.xcodeproj/project.pbxproj | 10 ++- 4 files changed, 154 insertions(+), 6 deletions(-) create mode 100644 Machines/AtariST/DMAController.cpp create mode 100644 Machines/AtariST/DMAController.hpp diff --git a/Machines/AtariST/AtariST.cpp b/Machines/AtariST/AtariST.cpp index 0cb34e042..877152580 100644 --- a/Machines/AtariST/AtariST.cpp +++ b/Machines/AtariST/AtariST.cpp @@ -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 speaker_; HalfCycles cycles_since_audio_update_; + JustInTimeActor dma_; + HalfCycles cycles_since_ikbd_update_; IntelligentKeyboard ikbd_; diff --git a/Machines/AtariST/DMAController.cpp b/Machines/AtariST/DMAController.cpp new file mode 100644 index 000000000..1b7586db3 --- /dev/null +++ b/Machines/AtariST/DMAController.cpp @@ -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 + +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()); +} diff --git a/Machines/AtariST/DMAController.hpp b/Machines/AtariST/DMAController.hpp new file mode 100644 index 000000000..e26ce8527 --- /dev/null +++ b/Machines/AtariST/DMAController.hpp @@ -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 +#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 */ diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index fe95f0d47..d47cae82d 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -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 = ""; }; 4B1E85801D176468001EF87D /* 6532Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 6532Tests.swift; sourceTree = ""; }; 4B1EDB431E39A0AC009D6819 /* chip.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chip.png; sourceTree = ""; }; + 4B21922B236523CB007FEEBC /* DMAController.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DMAController.cpp; sourceTree = ""; }; + 4B21922C236523CB007FEEBC /* DMAController.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DMAController.hpp; sourceTree = ""; }; 4B24095A1C45DF85004DA684 /* Stepper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Stepper.hpp; sourceTree = ""; }; 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 = ""; }; @@ -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 */,