mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Expands towards supporting multiple Macintosh models.
To provide another variable to help with bug isolation.
This commit is contained in:
parent
881feb1bd3
commit
85298319fa
@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
#include "StaticAnalyser.hpp"
|
||||
#include "Target.hpp"
|
||||
|
||||
Analyser::Static::TargetList Analyser::Static::Macintosh::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
|
||||
// This analyser can comprehend disks only.
|
||||
@ -15,7 +16,7 @@ Analyser::Static::TargetList Analyser::Static::Macintosh::GetTargets(const Media
|
||||
// If there is at least one disk, wave it through.
|
||||
Analyser::Static::TargetList targets;
|
||||
|
||||
using Target = Analyser::Static::Target;
|
||||
using Target = Analyser::Static::Macintosh::Target;
|
||||
auto *target = new Target;
|
||||
target->machine = Analyser::Machine::Macintosh;
|
||||
target->media = media;
|
||||
|
31
Analyser/Static/Macintosh/Target.hpp
Normal file
31
Analyser/Static/Macintosh/Target.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
//
|
||||
// Target.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 03/06/2019.
|
||||
// Copyright © 2019 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef Analyser_Static_Macintosh_Target_h
|
||||
#define Analyser_Static_Macintosh_Target_h
|
||||
|
||||
namespace Analyser {
|
||||
namespace Static {
|
||||
namespace Macintosh {
|
||||
|
||||
struct Target: public ::Analyser::Static::Target {
|
||||
enum class Model {
|
||||
Mac128k,
|
||||
Mac512k,
|
||||
Mac512ke,
|
||||
MacPlus
|
||||
};
|
||||
|
||||
Model model = Model::Mac128k;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Analyser_Static_Macintosh_Target_h */
|
@ -24,6 +24,8 @@
|
||||
#include "../../../Components/DiskII/IWM.hpp"
|
||||
#include "../../../Processors/68000/68000.hpp"
|
||||
|
||||
#include "../../../Analyser/Static/Macintosh/Target.hpp"
|
||||
|
||||
#include "../../Utility/MemoryPacker.hpp"
|
||||
|
||||
namespace {
|
||||
@ -35,7 +37,7 @@ const int CLOCK_RATE = 7833600;
|
||||
namespace Apple {
|
||||
namespace Macintosh {
|
||||
|
||||
class ConcreteMachine:
|
||||
template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachine:
|
||||
public Machine,
|
||||
public CRTMachine::Machine,
|
||||
public CPU::MC68000::BusHandler {
|
||||
@ -43,17 +45,45 @@ class ConcreteMachine:
|
||||
ConcreteMachine(const ROMMachine::ROMFetcher &rom_fetcher) :
|
||||
mc68000_(*this),
|
||||
iwm_(CLOCK_RATE),
|
||||
video_(ram_.data(), audio_, drive_speed_accumulator_),
|
||||
video_(ram_, audio_, drive_speed_accumulator_),
|
||||
via_(via_port_handler_),
|
||||
via_port_handler_(*this, clock_, keyboard_, video_, audio_, iwm_) {
|
||||
|
||||
// Select a ROM name and determine the proper ROM and RAM sizes
|
||||
// based on the machine model.
|
||||
using Model = Analyser::Static::Macintosh::Target::Model;
|
||||
std::string rom_name;
|
||||
uint32_t ram_size, rom_size;
|
||||
switch(model) {
|
||||
default:
|
||||
case Model::Mac128k:
|
||||
ram_size = 128*1024;
|
||||
rom_size = 64*1024;
|
||||
rom_name = "mac128k.rom";
|
||||
break;
|
||||
case Model::Mac512k:
|
||||
ram_size = 512*1024;
|
||||
rom_size = 64*1024;
|
||||
rom_name = "mac512k.rom";
|
||||
break;
|
||||
case Model::Mac512ke:
|
||||
case Model::MacPlus:
|
||||
ram_size = 512*1024;
|
||||
rom_size = 128*1024;
|
||||
rom_name = "macplus.rom";
|
||||
break;
|
||||
}
|
||||
ram_mask_ = (ram_size >> 1) - 1;
|
||||
rom_mask_ = (rom_size >> 1) - 1;
|
||||
video_.set_ram_mask(ram_mask_);
|
||||
|
||||
// Grab a copy of the ROM and convert it into big-endian data.
|
||||
const auto roms = rom_fetcher("Macintosh", { "mac128k.rom" });
|
||||
const auto roms = rom_fetcher("Macintosh", { rom_name });
|
||||
if(!roms[0]) {
|
||||
throw ROMMachine::Error::MissingROMs;
|
||||
}
|
||||
roms[0]->resize(64*1024);
|
||||
Memory::PackBigEndian16(*roms[0], rom_.data());
|
||||
roms[0]->resize(rom_size);
|
||||
Memory::PackBigEndian16(*roms[0], rom_);
|
||||
|
||||
// The Mac runs at 7.8336mHz.
|
||||
set_clock_rate(double(CLOCK_RATE));
|
||||
@ -125,7 +155,6 @@ class ConcreteMachine:
|
||||
|
||||
if(word_address >= 0x400000) {
|
||||
if(cycle.data_select_active()) {
|
||||
|
||||
const int register_address = word_address >> 8;
|
||||
|
||||
switch(word_address & 0x78f000) {
|
||||
@ -151,11 +180,32 @@ class ConcreteMachine:
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x780000:
|
||||
// Phase read.
|
||||
if(cycle.operation & Microcycle::Read) {
|
||||
cycle.value->halves.low = phase_ & 7;
|
||||
if(cycle.operation & Microcycle::SelectWord) cycle.value->halves.high = 0xff;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x480000: case 0x48f000:
|
||||
case 0x500000: case 0x580000: case 0x58f000:
|
||||
// Any word access here adjusts phase.
|
||||
if(cycle.operation & Microcycle::SelectWord) {
|
||||
++phase_;
|
||||
} else {
|
||||
// TODO: SCC access.
|
||||
printf("SCC access %06x\n", *cycle.address & 0xffffff);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if(cycle.operation & Microcycle::Read) {
|
||||
// printf("Unrecognised read %06x\n", *cycle.address & 0xffffff);
|
||||
printf("Unrecognised read %06x\n", *cycle.address & 0xffffff);
|
||||
cycle.value->halves.low = 0x00;
|
||||
if(cycle.operation & Microcycle::SelectWord) cycle.value->halves.high = 0xff;
|
||||
} else {
|
||||
printf("Unrecognised write %06x\n", *cycle.address & 0xffffff);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -173,11 +223,11 @@ class ConcreteMachine:
|
||||
(ROM_is_overlay_ && word_address >= 0x300000) ||
|
||||
(!ROM_is_overlay_ && word_address < 0x200000)
|
||||
) {
|
||||
memory_base = ram_.data();
|
||||
word_address %= ram_.size();
|
||||
memory_base = ram_;
|
||||
word_address &= ram_mask_;
|
||||
} else {
|
||||
memory_base = rom_.data();
|
||||
word_address %= rom_.size();
|
||||
memory_base = rom_;
|
||||
word_address &= rom_mask_;
|
||||
|
||||
// Disallow writes to ROM; also it doesn't mirror above 0x60000, ever.
|
||||
if(!(operation & Microcycle::Read) || word_address >= 0x300000) operation = 0;
|
||||
@ -363,9 +413,6 @@ class ConcreteMachine:
|
||||
IWM &iwm_;
|
||||
};
|
||||
|
||||
std::array<uint16_t, 32*1024> rom_;
|
||||
std::array<uint16_t, 64*1024> ram_;
|
||||
|
||||
CPU::MC68000::Processor<ConcreteMachine, true> mc68000_;
|
||||
|
||||
DriveSpeedAccumulator drive_speed_accumulator_;
|
||||
@ -388,6 +435,12 @@ class ConcreteMachine:
|
||||
HalfCycles time_since_iwm_update_;
|
||||
|
||||
bool ROM_is_overlay_ = true;
|
||||
int phase_ = 1;
|
||||
|
||||
uint32_t ram_mask_ = 0;
|
||||
uint32_t rom_mask_ = 0;
|
||||
uint16_t rom_[64*1024];
|
||||
uint16_t ram_[256*1024];
|
||||
};
|
||||
|
||||
}
|
||||
@ -396,7 +449,16 @@ class ConcreteMachine:
|
||||
using namespace Apple::Macintosh;
|
||||
|
||||
Machine *Machine::Macintosh(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher) {
|
||||
return new ConcreteMachine(rom_fetcher);
|
||||
auto *const mac_target = dynamic_cast<const Analyser::Static::Macintosh::Target *>(target);
|
||||
|
||||
using Model = Analyser::Static::Macintosh::Target::Model;
|
||||
switch(mac_target->model) {
|
||||
default:
|
||||
case Model::Mac128k: return new ConcreteMachine<Model::Mac128k>(rom_fetcher);
|
||||
case Model::Mac512k: return new ConcreteMachine<Model::Mac512k>(rom_fetcher);
|
||||
case Model::Mac512ke: return new ConcreteMachine<Model::Mac512ke>(rom_fetcher);
|
||||
case Model::MacPlus: return new ConcreteMachine<Model::MacPlus>(rom_fetcher);
|
||||
}
|
||||
}
|
||||
|
||||
Machine::~Machine() {}
|
||||
|
@ -150,13 +150,13 @@ void Video::run_for(HalfCycles duration) {
|
||||
/*
|
||||
Video: $1A700 and the alternate buffer starts at $12700; for a 512K Macintosh, add $60000 to these numbers.
|
||||
*/
|
||||
video_address_ = use_alternate_screen_buffer_ ? (0x12700 >> 1) : (0x1a700 >> 1);
|
||||
video_address_ = (use_alternate_screen_buffer_ ? (0xffff2700 >> 1) : (0xffffa700 >> 1)) & ram_mask_;
|
||||
|
||||
/*
|
||||
"The main sound buffer is at $1FD00 in a 128K Macintosh, and the alternate buffer is at $1A100;
|
||||
for a 512K Macintosh, add $60000 to these values."
|
||||
*/
|
||||
audio_address_ = use_alternate_audio_buffer_ ? (0x1a100 >> 1) : (0x1fd00 >> 1);
|
||||
audio_address_ = (use_alternate_audio_buffer_ ? (0xffffa100 >> 1) : (0xfffffd00 >> 1)) & ram_mask_;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -176,3 +176,7 @@ void Video::set_use_alternate_buffers(bool use_alternate_screen_buffer, bool use
|
||||
use_alternate_screen_buffer_ = use_alternate_screen_buffer;
|
||||
use_alternate_audio_buffer_ = use_alternate_audio_buffer;
|
||||
}
|
||||
|
||||
void Video::set_ram_mask(uint32_t mask) {
|
||||
ram_mask_ = mask;
|
||||
}
|
||||
|
@ -29,12 +29,15 @@ class Video {
|
||||
bool vsync();
|
||||
bool is_outputting();
|
||||
|
||||
void set_ram_mask(uint32_t);
|
||||
|
||||
private:
|
||||
DeferredAudio &audio_;
|
||||
DriveSpeedAccumulator &drive_speed_accumulator_;
|
||||
|
||||
Outputs::CRT::CRT crt_;
|
||||
uint16_t *ram_ = nullptr;
|
||||
uint32_t ram_mask_ = 0;
|
||||
|
||||
HalfCycles frame_position_;
|
||||
|
||||
|
@ -712,6 +712,7 @@
|
||||
4B046DC31CFE651500E9E45E /* CRTMachine.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CRTMachine.hpp; sourceTree = "<group>"; };
|
||||
4B047075201ABC180047AB0D /* Cartridge.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Cartridge.hpp; sourceTree = "<group>"; };
|
||||
4B049CDC1DA3C82F00322067 /* BCDTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BCDTest.swift; sourceTree = "<group>"; };
|
||||
4B04B65622A58CB40006AB58 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = "<group>"; };
|
||||
4B05401D219D1618001BF69C /* ScanTarget.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ScanTarget.cpp; path = ../../Outputs/ScanTarget.cpp; sourceTree = "<group>"; };
|
||||
4B055A6A1FAE763F0060FFFF /* Clock Signal Kiosk */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "Clock Signal Kiosk"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
4B055A771FAE78210060FFFF /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = ../../../../Library/Frameworks/SDL2.framework; sourceTree = SOURCE_ROOT; };
|
||||
@ -2791,6 +2792,7 @@
|
||||
children = (
|
||||
4BB4BFB722A4372E0069048D /* StaticAnalyser.hpp */,
|
||||
4BB4BFB822A4372E0069048D /* StaticAnalyser.cpp */,
|
||||
4B04B65622A58CB40006AB58 /* Target.hpp */,
|
||||
);
|
||||
path = Macintosh;
|
||||
sourceTree = "<group>";
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "../../../../../Analyser/Static/AmstradCPC/Target.hpp"
|
||||
#include "../../../../../Analyser/Static/AppleII/Target.hpp"
|
||||
#include "../../../../../Analyser/Static/Commodore/Target.hpp"
|
||||
#include "../../../../../Analyser/Static/Macintosh/Target.hpp"
|
||||
#include "../../../../../Analyser/Static/MSX/Target.hpp"
|
||||
#include "../../../../../Analyser/Static/Oric/Target.hpp"
|
||||
#include "../../../../../Analyser/Static/ZX8081/Target.hpp"
|
||||
@ -193,7 +194,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
|
||||
- (instancetype)initWithMacintoshModel:(CSMachineMacintoshModel)model {
|
||||
self = [super init];
|
||||
if(self) {
|
||||
using Target = Analyser::Static::Target;
|
||||
using Target = Analyser::Static::Macintosh::Target;
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
target->machine = Analyser::Machine::Macintosh;
|
||||
_targets.push_back(std::move(target));
|
||||
|
Loading…
x
Reference in New Issue
Block a user