1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-25 01:32:55 +00:00

Sketches out a blitter class.

This commit is contained in:
Thomas Harte 2021-07-22 18:43:07 -04:00
parent b3d55cc16d
commit e85db40b0f
4 changed files with 181 additions and 16 deletions

View File

@ -24,6 +24,8 @@
#define LOG_PREFIX "[Amiga] "
#include "../../Outputs/Log.hpp"
#include "Blitter.hpp"
namespace Amiga {
class ConcreteMachine:
@ -35,6 +37,7 @@ class ConcreteMachine:
public:
ConcreteMachine(const Analyser::Static::Amiga::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) :
mc68000_(*this),
blitter_(reinterpret_cast<uint16_t *>(memory_.chip_ram.data()), memory_.chip_ram.size()),
cia_a_handler_(memory_),
cia_a_(cia_a_handler_),
cia_b_(cia_b_handler_)
@ -48,7 +51,7 @@ class ConcreteMachine:
if(!request.validate(roms)) {
throw ROMMachine::Error::MissingROMs;
}
Memory::PackBigEndian16(roms.find(rom_name)->second, memory_.kickstart_.data());
Memory::PackBigEndian16(roms.find(rom_name)->second, memory_.kickstart.data());
// NTSC clock rate: 2*3.579545 = 7.15909Mhz.
// PAL clock rate: 7.09379Mhz.
@ -88,7 +91,7 @@ class ConcreteMachine:
// printf("%06x\n", *cycle.address);
// }
if(!memory_.regions_[address >> 18].read_write_mask) {
if(!memory_.regions[address >> 18].read_write_mask) {
if((cycle.operation & (Microcycle::SelectByte | Microcycle::SelectWord))) {
// Check for various potential chip accesses.
@ -155,6 +158,10 @@ class ConcreteMachine:
break;
// DMA management.
case Read(0x002):
LOG("DMA control and status read");
cycle.set_value16(dma_control_ | blitter_.get_status());
break;
case Write(0x096):
ApplySetClear(dma_control_);
LOG("DMA control modified by " << PADHEX(4) << cycle.value16() << "; is now " << std::bitset<16>{dma_control_});
@ -199,6 +206,34 @@ class ConcreteMachine:
cycle.set_value16(0xffff);
break;
// Blitter.
case Write(0x040): blitter_.set_control(0, cycle.value16()); break;
case Write(0x042): blitter_.set_control(1, cycle.value16()); break;
case Write(0x044): blitter_.set_first_word_mask(cycle.value16()); break;
case Write(0x046): blitter_.set_last_word_mask(cycle.value16()); break;
case Write(0x048): blitter_.set_pointer(2, 16, cycle.value16()); break;
case Write(0x04a): blitter_.set_pointer(2, 0, cycle.value16()); break;
case Write(0x04c): blitter_.set_pointer(1, 16, cycle.value16()); break;
case Write(0x04e): blitter_.set_pointer(1, 0, cycle.value16()); break;
case Write(0x050): blitter_.set_pointer(0, 16, cycle.value16()); break;
case Write(0x052): blitter_.set_pointer(0, 0, cycle.value16()); break;
case Write(0x054): blitter_.set_pointer(3, 16, cycle.value16()); break;
case Write(0x056): blitter_.set_pointer(3, 0, cycle.value16()); break;
case Write(0x058): blitter_.set_size(cycle.value16()); break;
case Write(0x05a): blitter_.set_minterms(cycle.value16()); break;
case Write(0x05c): blitter_.set_vertical_size(cycle.value16()); break;
case Write(0x05e): blitter_.set_horizontal_size(cycle.value16()); break;
case Write(0x060): blitter_.set_modulo(2, cycle.value16()); break;
case Write(0x062): blitter_.set_modulo(1, cycle.value16()); break;
case Write(0x064): blitter_.set_modulo(0, cycle.value16()); break;
case Write(0x066): blitter_.set_modulo(3, cycle.value16()); break;
case Write(0x070): blitter_.set_data(2, cycle.value16()); break;
case Write(0x072): blitter_.set_data(1, cycle.value16()); break;
case Write(0x074): blitter_.set_data(0, cycle.value16()); break;
// Colour palette.
case Write(0x180): case Write(0x182): case Write(0x184): case Write(0x186):
@ -229,8 +264,8 @@ class ConcreteMachine:
} else {
// A regular memory access.
cycle.apply(
&memory_.regions_[address >> 18].contents[address],
memory_.regions_[address >> 18].read_write_mask
&memory_.regions[address >> 18].contents[address],
memory_.regions[address >> 18].read_write_mask
);
}
@ -243,13 +278,13 @@ class ConcreteMachine:
// MARK: - Memory map.
struct MemoryMap {
public:
std::array<uint8_t, 512*1024> ram_{};
std::array<uint8_t, 512*1024> kickstart_{0xff};
std::array<uint8_t, 512*1024> chip_ram{};
std::array<uint8_t, 512*1024> kickstart{0xff};
struct MemoryRegion {
uint8_t *contents = nullptr;
unsigned int read_write_mask = 0;
} regions_[64]; // i.e. top six bits are used as an index.
} regions[64]; // i.e. top six bits are used as an index.
MemoryMap() {
// Address spaces that matter:
@ -267,7 +302,7 @@ class ConcreteMachine:
// f0'0000 — : 512kb Kickstart (or possibly just an extra 512kb reserved for hypothetical 1mb Kickstart?).
// f8'0000 — : 256kb Kickstart if 2.04 or higher.
// fc'0000 : 256kb Kickstart otherwise.
set_region(0xfc'0000, 0x1'00'0000, kickstart_.data(), CPU::MC68000::Microcycle::PermitRead);
set_region(0xfc'0000, 0x1'00'0000, kickstart.data(), CPU::MC68000::Microcycle::PermitRead);
reset();
}
@ -282,13 +317,10 @@ class ConcreteMachine:
overlay_ = enabled;
if(enabled) {
set_region(0x00'0000, 0x08'0000, kickstart_.data(), CPU::MC68000::Microcycle::PermitRead);
set_region(0x00'0000, 0x08'0000, kickstart.data(), CPU::MC68000::Microcycle::PermitRead);
} else {
// Mirror RAM to fill out the address range up to $20'0000 (?)
set_region(0x00'0000, 0x08'0000, ram_.data(), CPU::MC68000::Microcycle::PermitRead | CPU::MC68000::Microcycle::PermitWrite);
set_region(0x08'0000, 0x10'0000, ram_.data(), CPU::MC68000::Microcycle::PermitRead | CPU::MC68000::Microcycle::PermitWrite);
set_region(0x10'0000, 0x18'0000, ram_.data(), CPU::MC68000::Microcycle::PermitRead | CPU::MC68000::Microcycle::PermitWrite);
set_region(0x18'0000, 0x20'0000, ram_.data(), CPU::MC68000::Microcycle::PermitRead | CPU::MC68000::Microcycle::PermitWrite);
set_region(0x00'0000, 0x08'0000, chip_ram.data(), CPU::MC68000::Microcycle::PermitRead | CPU::MC68000::Microcycle::PermitWrite);
}
}
@ -301,8 +333,8 @@ class ConcreteMachine:
base -= start;
for(int c = start >> 18; c < end >> 18; c++) {
regions_[c].contents = base;
regions_[c].read_write_mask = read_write_mask;
regions[c].contents = base;
regions[c].read_write_mask = read_write_mask;
}
}
} memory_;
@ -316,9 +348,10 @@ class ConcreteMachine:
// TODO.
}
// MARK: - DMA control.
// MARK: - DMA control, blitter and Paula.
uint16_t dma_control_ = 0;
Blitter blitter_;
// MARK: - CIAs.

View File

@ -0,0 +1,69 @@
//
// Blitter.cpp
// Clock Signal
//
// Created by Thomas Harte on 22/07/2021.
// Copyright © 2021 Thomas Harte. All rights reserved.
//
#include "Blitter.hpp"
//#define NDEBUG
#define LOG_PREFIX "[Blitter] "
#include "../../Outputs/Log.hpp"
using namespace Amiga;
Blitter::Blitter(uint16_t *ram, size_t size) : ram_(ram), ram_size_(size) {}
void Blitter::set_control(int index, uint16_t value) {
LOG("Set control " << index << " to " << PADHEX(4) << value);
}
void Blitter::set_first_word_mask(uint16_t value) {
LOG("Set first word mask: " << PADHEX(4) << value);
}
void Blitter::set_last_word_mask(uint16_t value) {
LOG("Set last word mask: " << PADHEX(4) << value);
}
void Blitter::set_pointer(int channel, int shift, uint16_t value) {
LOG("Set pointer " << channel << " shift " << shift << " to " << PADHEX(4) << value);
}
void Blitter::set_size(uint16_t value) {
LOG("Set size " << PADHEX(4) << value);
}
void Blitter::set_minterms(uint16_t value) {
LOG("Set minterms " << PADHEX(4) << value);
}
void Blitter::set_vertical_size(uint16_t value) {
LOG("Set vertical size " << PADHEX(4) << value);
}
void Blitter::set_horizontal_size(uint16_t value) {
LOG("Set horizontal size " << PADHEX(4) << value);
}
void Blitter::set_modulo(int channel, uint16_t value) {
LOG("Set modulo size " << channel << " to " << PADHEX(4) << value);
}
void Blitter::set_data(int channel, uint16_t value) {
LOG("Set data " << channel << " to " << PADHEX(4) << value);
}
uint16_t Blitter::get_status() {
LOG("Returned dummy status");
return 0;
}
Cycles Blitter::get_remaining_cycles() {
return Cycles(0);
}
void Blitter::run_for(Cycles) {
}

View File

@ -0,0 +1,55 @@
//
// Blitter.hpp
// Clock Signal
//
// Created by Thomas Harte on 22/07/2021.
// Copyright © 2021 Thomas Harte. All rights reserved.
//
#ifndef Blitter_hpp
#define Blitter_hpp
#include <cstddef>
#include <cstdint>
#include "../../ClockReceiver/ClockReceiver.hpp"
namespace Amiga {
class Blitter {
public:
Blitter(uint16_t *ram, size_t size);
// Various setters; it's assumed that address decoding is handled externally.
//
// In all cases where a channel is identified numerically, it's taken that
// 0 = A, 1 = B, 2 = C, 3 = D.
void set_control(int index, uint16_t value);
void set_first_word_mask(uint16_t value);
void set_last_word_mask(uint16_t value);
void set_pointer(int channel, int shift, uint16_t value);
void set_size(uint16_t value);
void set_minterms(uint16_t value);
void set_vertical_size(uint16_t value);
void set_horizontal_size(uint16_t value);
void set_modulo(int channel, uint16_t value);
void set_data(int channel, uint16_t value);
uint16_t get_status();
/// @returns The number of 'cycles' required to complete the current
/// operation, if any, or Cycles(0) if no operation is pending.
Cycles get_remaining_cycles();
/// Advances the stated number of cycles.
void run_for(Cycles);
private:
uint16_t *const ram_;
const size_t ram_size_;
};
}
#endif /* Blitter_hpp */

View File

@ -580,6 +580,8 @@
4B9D0C4B22C7D70A00DE1AD3 /* 68000BCDTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B9D0C4A22C7D70900DE1AD3 /* 68000BCDTests.mm */; };
4B9D0C4D22C7DA1A00DE1AD3 /* 68000ControlFlowTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B9D0C4C22C7DA1A00DE1AD3 /* 68000ControlFlowTests.mm */; };
4B9D0C4F22C7E0CF00DE1AD3 /* 68000RollShiftTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B9D0C4E22C7E0CF00DE1AD3 /* 68000RollShiftTests.mm */; };
4B9EC0E226AA27BA0060A31F /* Blitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9EC0E126AA27BA0060A31F /* Blitter.cpp */; };
4B9EC0E326AA27BA0060A31F /* Blitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9EC0E126AA27BA0060A31F /* Blitter.cpp */; };
4B9F11C92272375400701480 /* qltrace.txt.gz in Resources */ = {isa = PBXBuildFile; fileRef = 4B9F11C82272375400701480 /* qltrace.txt.gz */; };
4B9F11CA2272433900701480 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B69FB451C4D950F00B5F0AA /* libz.tbd */; };
4B9F11CC22729B3600701480 /* OPCLOGR2.BIN in Resources */ = {isa = PBXBuildFile; fileRef = 4B9F11CB22729B3500701480 /* OPCLOGR2.BIN */; };
@ -1584,6 +1586,8 @@
4B9D0C4A22C7D70900DE1AD3 /* 68000BCDTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = 68000BCDTests.mm; sourceTree = "<group>"; };
4B9D0C4C22C7DA1A00DE1AD3 /* 68000ControlFlowTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = 68000ControlFlowTests.mm; sourceTree = "<group>"; };
4B9D0C4E22C7E0CF00DE1AD3 /* 68000RollShiftTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = 68000RollShiftTests.mm; sourceTree = "<group>"; };
4B9EC0E026AA260C0060A31F /* Blitter.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Blitter.hpp; sourceTree = "<group>"; };
4B9EC0E126AA27BA0060A31F /* Blitter.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Blitter.cpp; sourceTree = "<group>"; };
4B9F11C82272375400701480 /* qltrace.txt.gz */ = {isa = PBXFileReference; lastKnownFileType = archive.gzip; path = qltrace.txt.gz; sourceTree = "<group>"; };
4B9F11CB22729B3500701480 /* OPCLOGR2.BIN */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = OPCLOGR2.BIN; path = "68000 Coverage/OPCLOGR2.BIN"; sourceTree = "<group>"; };
4BA0F68C1EEA0E8400E9489E /* ZX8081.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ZX8081.cpp; sourceTree = "<group>"; };
@ -4266,6 +4270,8 @@
children = (
4BC080D726A25ADA00D03FD8 /* Amiga.hpp */,
4BC080D826A25ADA00D03FD8 /* Amiga.cpp */,
4B9EC0E026AA260C0060A31F /* Blitter.hpp */,
4B9EC0E126AA27BA0060A31F /* Blitter.cpp */,
);
path = Amiga;
sourceTree = "<group>";
@ -5358,6 +5364,7 @@
4BF437EF209D0F7E008CBD6B /* SegmentParser.cpp in Sources */,
4B055AD11FAE9B030060FFFF /* Video.cpp in Sources */,
4BB4BFBA22A4372F0069048D /* StaticAnalyser.cpp in Sources */,
4B9EC0E326AA27BA0060A31F /* Blitter.cpp in Sources */,
4B055AA21FAE85DA0060FFFF /* SSD.cpp in Sources */,
4B2E86E325DC95150024F1E9 /* Joystick.cpp in Sources */,
4BEBFB4E2002C4BF000708CC /* FAT12.cpp in Sources */,
@ -5681,6 +5688,7 @@
4BCA6CC81D9DD9F000C2D7B2 /* CommodoreROM.cpp in Sources */,
4BC1317A2346DF2B00E4FF3D /* MSA.cpp in Sources */,
4BEBFB4D2002C4BF000708CC /* FAT12.cpp in Sources */,
4B9EC0E226AA27BA0060A31F /* Blitter.cpp in Sources */,
4BBFBB6C1EE8401E00C01E7A /* ZX8081.cpp in Sources */,
4B83348A1F5DB94B0097E338 /* IRQDelegatePortHandler.cpp in Sources */,
4B8DD3862634D37E00B3C866 /* SNA.cpp in Sources */,