mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-02 16:38:51 +00:00
Moves the Copper into its own file.
This commit is contained in:
parent
0eeaaa150a
commit
245b7baa61
@ -62,79 +62,6 @@ void Chipset::posit_interrupt(InterruptFlag flag) {
|
||||
update_interrupts();
|
||||
}
|
||||
|
||||
bool Chipset::Copper::advance(uint16_t position) {
|
||||
switch(state_) {
|
||||
default: return false;
|
||||
|
||||
case State::Waiting:
|
||||
// TODO: blitter-finished bit.
|
||||
if((position & position_mask_) >= instruction_[0]) {
|
||||
state_ = State::FetchFirstWord;
|
||||
}
|
||||
return false;
|
||||
|
||||
case State::FetchFirstWord:
|
||||
instruction_[0] = ram_[address_ & ram_mask_];
|
||||
++address_;
|
||||
state_ = State::FetchSecondWord;
|
||||
break;
|
||||
|
||||
case State::FetchSecondWord: {
|
||||
const bool should_skip_move = skip_next_;
|
||||
skip_next_ = false;
|
||||
|
||||
instruction_[1] = ram_[address_ & ram_mask_];
|
||||
++address_;
|
||||
|
||||
if(!(instruction_[0] & 1)) {
|
||||
// A MOVE.
|
||||
|
||||
if(!should_skip_move) {
|
||||
// Stop if this move would be a privilege violation.
|
||||
instruction_[0] &= 0x1fe;
|
||||
if((instruction_[0] < 0x10) || (instruction_[0] < 0x20 && !(control_&1))) {
|
||||
LOG("Invalid Copper MOVE to " << PADHEX(4) << instruction_[0] << "; stopping");
|
||||
state_ = State::Stopped;
|
||||
break;
|
||||
}
|
||||
|
||||
// Construct a 68000-esque Microcycle in order to be able to perform the access.
|
||||
CPU::MC68000::Microcycle cycle;
|
||||
cycle.operation = CPU::MC68000::Microcycle::SelectWord;
|
||||
uint32_t full_address = instruction_[0];
|
||||
CPU::RegisterPair16 data = instruction_[1];
|
||||
cycle.address = &full_address;
|
||||
cycle.value = &data;
|
||||
chipset_.perform(cycle);
|
||||
}
|
||||
|
||||
// Roll onto the next command.
|
||||
state_ = State::FetchFirstWord;
|
||||
break;
|
||||
}
|
||||
|
||||
// Prepare for a position comparison.
|
||||
position_mask_ = 0x8001 | (instruction_[1] & 0x7ffe);
|
||||
instruction_[0] &= position_mask_;
|
||||
|
||||
if(!(instruction_[1] & 1)) {
|
||||
// A WAIT. Just note that this is now waiting; the proper test
|
||||
// will be applied from the next potential `advance` onwards.
|
||||
state_ = State::Waiting;
|
||||
break;
|
||||
}
|
||||
|
||||
// Neither a WAIT nor a MOVE => a SKIP.
|
||||
|
||||
// TODO: blitter-finished bit.
|
||||
skip_next_ = (position & position_mask_) >= instruction_[0];
|
||||
state_ = State::FetchFirstWord;
|
||||
} break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <int cycle> void Chipset::output() {
|
||||
// Notes to self on guesses below:
|
||||
//
|
||||
|
@ -15,8 +15,9 @@
|
||||
#include "../../Processors/68000/68000.hpp"
|
||||
#include "../../Outputs/CRT/CRT.hpp"
|
||||
|
||||
#include "DMADevice.hpp"
|
||||
#include "Blitter.hpp"
|
||||
#include "Copper.hpp"
|
||||
#include "DMADevice.hpp"
|
||||
|
||||
namespace Amiga {
|
||||
|
||||
@ -191,42 +192,7 @@ class Chipset {
|
||||
|
||||
// MARK: - Copper.
|
||||
|
||||
class Copper: public DMADevice<2> {
|
||||
public:
|
||||
using DMADevice<2>::DMADevice;
|
||||
|
||||
/// Offers a DMA slot to the Copper, specifying the current beam position.
|
||||
///
|
||||
/// @returns @c true if the slot was used; @c false otherwise.
|
||||
bool advance(uint16_t position);
|
||||
|
||||
/// Forces a reload of address @c id (i.e. 0 or 1) and restarts the Copper.
|
||||
template <int id> void reload() {
|
||||
address_ = pointer_[id];
|
||||
state_ = State::FetchFirstWord;
|
||||
}
|
||||
|
||||
/// Sets the Copper control word.
|
||||
void set_control(uint16_t c) {
|
||||
control_ = c;
|
||||
}
|
||||
|
||||
/// Forces the Copper into the stopped state.
|
||||
void stop() {
|
||||
state_ = State::Stopped;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t address_ = 0;
|
||||
uint16_t control_ = 0;
|
||||
|
||||
enum class State {
|
||||
FetchFirstWord, FetchSecondWord, Waiting, Stopped,
|
||||
} state_ = State::Stopped;
|
||||
bool skip_next_ = false;
|
||||
uint16_t instruction_[2]{};
|
||||
uint16_t position_mask_ = 0xffff;
|
||||
} copper_;
|
||||
Copper copper_;
|
||||
|
||||
// MARK: - Serial port.
|
||||
|
||||
|
91
Machines/Amiga/Copper.cpp
Normal file
91
Machines/Amiga/Copper.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
//
|
||||
// Copper.cpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 16/09/2021.
|
||||
// Copyright © 2021 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define NDEBUG
|
||||
#define LOG_PREFIX "[Copper] "
|
||||
#include "../../Outputs/Log.hpp"
|
||||
|
||||
#include "Chipset.hpp"
|
||||
#include "Copper.hpp"
|
||||
|
||||
using namespace Amiga;
|
||||
|
||||
bool Copper::advance(uint16_t position) {
|
||||
switch(state_) {
|
||||
default: return false;
|
||||
|
||||
case State::Waiting:
|
||||
// TODO: blitter-finished bit.
|
||||
if((position & position_mask_) >= instruction_[0]) {
|
||||
state_ = State::FetchFirstWord;
|
||||
}
|
||||
return false;
|
||||
|
||||
case State::FetchFirstWord:
|
||||
instruction_[0] = ram_[address_ & ram_mask_];
|
||||
++address_;
|
||||
state_ = State::FetchSecondWord;
|
||||
break;
|
||||
|
||||
case State::FetchSecondWord: {
|
||||
const bool should_skip_move = skip_next_;
|
||||
skip_next_ = false;
|
||||
|
||||
instruction_[1] = ram_[address_ & ram_mask_];
|
||||
++address_;
|
||||
|
||||
if(!(instruction_[0] & 1)) {
|
||||
// A MOVE.
|
||||
|
||||
if(!should_skip_move) {
|
||||
// Stop if this move would be a privilege violation.
|
||||
instruction_[0] &= 0x1fe;
|
||||
if((instruction_[0] < 0x10) || (instruction_[0] < 0x20 && !(control_&1))) {
|
||||
LOG("Invalid MOVE to " << PADHEX(4) << instruction_[0] << "; stopping");
|
||||
state_ = State::Stopped;
|
||||
break;
|
||||
}
|
||||
|
||||
// Construct a 68000-esque Microcycle in order to be able to perform the access.
|
||||
CPU::MC68000::Microcycle cycle;
|
||||
cycle.operation = CPU::MC68000::Microcycle::SelectWord;
|
||||
uint32_t full_address = instruction_[0];
|
||||
CPU::RegisterPair16 data = instruction_[1];
|
||||
cycle.address = &full_address;
|
||||
cycle.value = &data;
|
||||
chipset_.perform(cycle);
|
||||
}
|
||||
|
||||
// Roll onto the next command.
|
||||
state_ = State::FetchFirstWord;
|
||||
break;
|
||||
}
|
||||
|
||||
// Prepare for a position comparison.
|
||||
position_mask_ = 0x8001 | (instruction_[1] & 0x7ffe);
|
||||
instruction_[0] &= position_mask_;
|
||||
|
||||
if(!(instruction_[1] & 1)) {
|
||||
// A WAIT. Just note that this is now waiting; the proper test
|
||||
// will be applied from the next potential `advance` onwards.
|
||||
state_ = State::Waiting;
|
||||
break;
|
||||
}
|
||||
|
||||
// Neither a WAIT nor a MOVE => a SKIP.
|
||||
|
||||
// TODO: blitter-finished bit.
|
||||
skip_next_ = (position & position_mask_) >= instruction_[0];
|
||||
state_ = State::FetchFirstWord;
|
||||
} break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
55
Machines/Amiga/Copper.hpp
Normal file
55
Machines/Amiga/Copper.hpp
Normal file
@ -0,0 +1,55 @@
|
||||
//
|
||||
// Copper.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 16/09/2021.
|
||||
// Copyright © 2021 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef Copper_h
|
||||
#define Copper_h
|
||||
|
||||
#include "DMADevice.hpp"
|
||||
|
||||
namespace Amiga {
|
||||
|
||||
class Copper: public DMADevice<2> {
|
||||
public:
|
||||
using DMADevice<2>::DMADevice;
|
||||
|
||||
/// Offers a DMA slot to the Copper, specifying the current beam position.
|
||||
///
|
||||
/// @returns @c true if the slot was used; @c false otherwise.
|
||||
bool advance(uint16_t position);
|
||||
|
||||
/// Forces a reload of address @c id (i.e. 0 or 1) and restarts the Copper.
|
||||
template <int id> void reload() {
|
||||
address_ = pointer_[id];
|
||||
state_ = State::FetchFirstWord;
|
||||
}
|
||||
|
||||
/// Sets the Copper control word.
|
||||
void set_control(uint16_t c) {
|
||||
control_ = c;
|
||||
}
|
||||
|
||||
/// Forces the Copper into the stopped state.
|
||||
void stop() {
|
||||
state_ = State::Stopped;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t address_ = 0;
|
||||
uint16_t control_ = 0;
|
||||
|
||||
enum class State {
|
||||
FetchFirstWord, FetchSecondWord, Waiting, Stopped,
|
||||
} state_ = State::Stopped;
|
||||
bool skip_next_ = false;
|
||||
uint16_t instruction_[2]{};
|
||||
uint16_t position_mask_ = 0xffff;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* Copper_h */
|
@ -915,6 +915,8 @@
|
||||
4BC57CDA2436A62900FBC404 /* State.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC57CD82436A62900FBC404 /* State.cpp */; };
|
||||
4BC5C3E022C994CD00795658 /* 68000MoveTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BC5C3DF22C994CC00795658 /* 68000MoveTests.mm */; };
|
||||
4BC5FC3020CDDDEF00410AA0 /* AppleIIOptions.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4BC5FC2E20CDDDEE00410AA0 /* AppleIIOptions.xib */; };
|
||||
4BC6236D26F4235400F83DFE /* Copper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC6236C26F4235400F83DFE /* Copper.cpp */; };
|
||||
4BC6236E26F4235400F83DFE /* Copper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC6236C26F4235400F83DFE /* Copper.cpp */; };
|
||||
4BC751B21D157E61006C31D9 /* 6522Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BC751B11D157E61006C31D9 /* 6522Tests.swift */; };
|
||||
4BC76E691C98E31700E6EF73 /* FIRFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */; };
|
||||
4BC890D3230F86020025A55A /* DirectAccessDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC890D1230F86020025A55A /* DirectAccessDevice.cpp */; };
|
||||
@ -1962,6 +1964,8 @@
|
||||
4BC5C3DF22C994CC00795658 /* 68000MoveTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = 68000MoveTests.mm; sourceTree = "<group>"; };
|
||||
4BC5FC2F20CDDDEE00410AA0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/AppleIIOptions.xib"; sourceTree = SOURCE_ROOT; };
|
||||
4BC6236A26F178DA00F83DFE /* DMADevice.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DMADevice.hpp; sourceTree = "<group>"; };
|
||||
4BC6236B26F4224300F83DFE /* Copper.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Copper.hpp; sourceTree = "<group>"; };
|
||||
4BC6236C26F4235400F83DFE /* Copper.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Copper.cpp; sourceTree = "<group>"; };
|
||||
4BC751B11D157E61006C31D9 /* 6522Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 6522Tests.swift; sourceTree = "<group>"; };
|
||||
4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FIRFilter.cpp; sourceTree = "<group>"; };
|
||||
4BC76E681C98E31700E6EF73 /* FIRFilter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FIRFilter.hpp; sourceTree = "<group>"; };
|
||||
@ -4281,10 +4285,12 @@
|
||||
4BC080D826A25ADA00D03FD8 /* Amiga.cpp */,
|
||||
4B9EC0E126AA27BA0060A31F /* Blitter.cpp */,
|
||||
4B9EC0E426AA4A660060A31F /* Chipset.cpp */,
|
||||
4BC6236C26F4235400F83DFE /* Copper.cpp */,
|
||||
4B9EC0E826B384080060A31F /* Keyboard.cpp */,
|
||||
4BC080D726A25ADA00D03FD8 /* Amiga.hpp */,
|
||||
4B9EC0E026AA260C0060A31F /* Blitter.hpp */,
|
||||
4B9EC0E526AA4A660060A31F /* Chipset.hpp */,
|
||||
4BC6236B26F4224300F83DFE /* Copper.hpp */,
|
||||
4BC6236A26F178DA00F83DFE /* DMADevice.hpp */,
|
||||
4B9EC0E926B384080060A31F /* Keyboard.hpp */,
|
||||
);
|
||||
@ -5428,6 +5434,7 @@
|
||||
4B055AA01FAE85DA0060FFFF /* MFMSectorDump.cpp in Sources */,
|
||||
4BEBFB522002DB30000708CC /* DiskROM.cpp in Sources */,
|
||||
4BC23A2D2467600F001A6030 /* OPLL.cpp in Sources */,
|
||||
4BC6236E26F4235400F83DFE /* Copper.cpp in Sources */,
|
||||
4B055AA11FAE85DA0060FFFF /* OricMFMDSK.cpp in Sources */,
|
||||
4B1EC717255398B000A1F44B /* Sound.cpp in Sources */,
|
||||
4BB8616F24E22DC500A00E03 /* BufferingScanTarget.cpp in Sources */,
|
||||
@ -5575,6 +5582,7 @@
|
||||
4B0ACC2A23775819008902D0 /* Video.cpp in Sources */,
|
||||
4B54C0BF1F8D8F450050900F /* Keyboard.cpp in Sources */,
|
||||
4B3FE75E1F3CF68B00448EE4 /* CPM.cpp in Sources */,
|
||||
4BC6236D26F4235400F83DFE /* Copper.cpp in Sources */,
|
||||
4B2BFDB21DAEF5FF001A68B8 /* Video.cpp in Sources */,
|
||||
4BEDA3BF25B25563000C2DBD /* Decoder.cpp in Sources */,
|
||||
4B051C95266EF50200CA44E8 /* AppleIIController.swift in Sources */,
|
||||
|
Loading…
x
Reference in New Issue
Block a user