mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-25 16:31:42 +00:00
Sketches out a blitter class.
This commit is contained in:
parent
b3d55cc16d
commit
e85db40b0f
@ -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.
|
||||
|
||||
|
69
Machines/Amiga/Blitter.cpp
Normal file
69
Machines/Amiga/Blitter.cpp
Normal 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) {
|
||||
}
|
55
Machines/Amiga/Blitter.hpp
Normal file
55
Machines/Amiga/Blitter.hpp
Normal 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 */
|
@ -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 */,
|
||||
|
Loading…
Reference in New Issue
Block a user