mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-24 12:30:17 +00:00
Attempts to bring card support to the Apple II, and adds a 'has disk' flag.
This commit is contained in:
parent
e92e06a5f4
commit
7463edaa1b
@ -14,6 +14,8 @@ Analyser::Static::TargetList Analyser::Static::AppleII::GetTargets(const Media &
|
||||
target->machine = Machine::AppleII;
|
||||
target->media = media;
|
||||
|
||||
target->has_disk = !target->media.disks.empty();
|
||||
|
||||
TargetList targets;
|
||||
targets.push_back(std::move(target));
|
||||
return targets;
|
||||
|
@ -16,7 +16,7 @@ namespace Static {
|
||||
namespace AppleII {
|
||||
|
||||
struct Target: public ::Analyser::Static::Target {
|
||||
bool has_disk_; // TODO: Disk II versus IWM?
|
||||
bool has_disk; // TODO: Disk II versus IWM?
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -18,8 +18,11 @@
|
||||
|
||||
#include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp"
|
||||
|
||||
#include "Card.hpp"
|
||||
#include "Video.hpp"
|
||||
|
||||
#include "../../Analyser/Static/AppleII/Target.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace {
|
||||
@ -57,6 +60,16 @@ class ConcreteMachine:
|
||||
void update_audio() {
|
||||
speaker_.run_for(audio_queue_, cycles_since_audio_update_.divide(Cycles(audio_divider)));
|
||||
}
|
||||
void update_cards() {
|
||||
cycles_since_card_update_ += stretched_cycles_since_card_update_ / 7;
|
||||
stretched_cycles_since_card_update_ %= 7;
|
||||
for(int c = 0; c < 7; ++c) {
|
||||
if(cards_[c])
|
||||
cards_[c]->run_for(cycles_since_card_update_, stretched_cycles_since_card_update_);
|
||||
}
|
||||
cycles_since_card_update_ = 0;
|
||||
stretched_cycles_since_card_update_ = 0;
|
||||
}
|
||||
|
||||
uint8_t ram_[48*1024];
|
||||
std::vector<uint8_t> rom_;
|
||||
@ -69,6 +82,11 @@ class ConcreteMachine:
|
||||
Outputs::Speaker::LowpassSpeaker<Audio::Toggle> speaker_;
|
||||
Cycles cycles_since_audio_update_;
|
||||
|
||||
ROMMachine::ROMFetcher rom_fetcher_;
|
||||
AppleII::Card *cards_[7] = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
|
||||
Cycles cycles_since_card_update_;
|
||||
int stretched_cycles_since_card_update_ = 0;
|
||||
|
||||
public:
|
||||
ConcreteMachine():
|
||||
m6502_(*this),
|
||||
@ -110,6 +128,7 @@ class ConcreteMachine:
|
||||
|
||||
Cycles perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) {
|
||||
++ cycles_since_video_update_;
|
||||
++ cycles_since_card_update_;
|
||||
cycles_since_audio_update_ += Cycles(7);
|
||||
|
||||
switch(address) {
|
||||
@ -123,7 +142,6 @@ class ConcreteMachine:
|
||||
switch(address) {
|
||||
default:
|
||||
// printf("Unknown access to %04x\n", address);
|
||||
*value = 0xff;
|
||||
break;
|
||||
case 0xc000:
|
||||
*value = keyboard_input_;
|
||||
@ -160,6 +178,28 @@ class ConcreteMachine:
|
||||
break;
|
||||
}
|
||||
|
||||
if(address >= 0xc100 && address < 0xc800) {
|
||||
/*
|
||||
Decode the area conventionally used by cards for ROMs:
|
||||
0xCn00 — 0xCnff: card n.
|
||||
*/
|
||||
const int card_number = (address - 0xc100) >> 8;
|
||||
if(cards_[card_number]) {
|
||||
update_cards();
|
||||
cards_[card_number]->perform_bus_operation(operation, address & 0xff, value);
|
||||
}
|
||||
} else if(address >= 0xc090 && address < 0xc100) {
|
||||
/*
|
||||
Decode the area conventionally used by cards for registers:
|
||||
C0n0--C0nF: card n - 8.
|
||||
*/
|
||||
const int card_number = (address - 0xc080) >> 4;
|
||||
if(cards_[card_number]) {
|
||||
update_cards();
|
||||
cards_[card_number]->perform_bus_operation(operation, address, value);
|
||||
}
|
||||
}
|
||||
|
||||
// The Apple II has a slightly weird timing pattern: every 65th CPU cycle is stretched
|
||||
// by an extra 1/7th. That's because one cycle lasts 3.5 NTSC colour clocks, so after
|
||||
// 65 cycles a full line of 227.5 colour clocks have passed. But the high-rate binary
|
||||
@ -169,6 +209,7 @@ class ConcreteMachine:
|
||||
cycles_into_current_line_ = (cycles_into_current_line_ + 1) % 65;
|
||||
if(!cycles_into_current_line_) {
|
||||
++ cycles_since_audio_update_;
|
||||
++ stretched_cycles_since_card_update_;
|
||||
}
|
||||
|
||||
return Cycles(1);
|
||||
@ -180,7 +221,7 @@ class ConcreteMachine:
|
||||
audio_queue_.perform();
|
||||
}
|
||||
|
||||
bool set_rom_fetcher(const std::function<std::vector<std::unique_ptr<std::vector<uint8_t>>>(const std::string &machine, const std::vector<std::string> &names)> &roms_with_names) override {
|
||||
bool set_rom_fetcher(const ROMMachine::ROMFetcher &roms_with_names) override {
|
||||
auto roms = roms_with_names(
|
||||
"AppleII",
|
||||
{
|
||||
@ -194,6 +235,8 @@ class ConcreteMachine:
|
||||
|
||||
character_rom_ = std::move(*roms[1]);
|
||||
|
||||
rom_fetcher_ = roms_with_names;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -223,6 +266,10 @@ class ConcreteMachine:
|
||||
|
||||
// MARK: ConfigurationTarget
|
||||
void configure_as_target(const Analyser::Static::Target *target) override {
|
||||
auto *const apple_target = dynamic_cast<const Analyser::Static::AppleII::Target *>(target);
|
||||
if(apple_target->has_disk) {
|
||||
// ... add Disk II
|
||||
}
|
||||
}
|
||||
|
||||
bool insert_media(const Analyser::Static::Media &media) override {
|
||||
|
27
Machines/AppleII/Card.hpp
Normal file
27
Machines/AppleII/Card.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
//
|
||||
// Card.h
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 23/04/2018.
|
||||
// Copyright © 2018 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef Card_h
|
||||
#define Card_h
|
||||
|
||||
#include "../../ClockReceiver/ClockReceiver.hpp"
|
||||
|
||||
namespace AppleII {
|
||||
|
||||
class Card {
|
||||
public:
|
||||
/*! Advances time by @c cycles, of which @c stretches were stretched. */
|
||||
virtual void run_for(Cycles half_cycles, int stretches) {}
|
||||
|
||||
/*! Performs a bus operation; the card is implicitly selected. */
|
||||
virtual void perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* Card_h */
|
@ -1332,6 +1332,7 @@
|
||||
4BBFBB6A1EE8401E00C01E7A /* ZX8081.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ZX8081.cpp; path = Parsers/ZX8081.cpp; sourceTree = "<group>"; };
|
||||
4BBFBB6B1EE8401E00C01E7A /* ZX8081.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ZX8081.hpp; path = Parsers/ZX8081.hpp; sourceTree = "<group>"; };
|
||||
4BBFFEE51F7B27F1005F3FEB /* TrackSerialiser.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TrackSerialiser.cpp; sourceTree = "<group>"; };
|
||||
4BC39565208EDFCE0044766B /* Card.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Card.hpp; sourceTree = "<group>"; };
|
||||
4BC3B74D1CD194CC00F86E85 /* Shader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Shader.cpp; sourceTree = "<group>"; };
|
||||
4BC3B74E1CD194CC00F86E85 /* Shader.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Shader.hpp; sourceTree = "<group>"; };
|
||||
4BC3B7501CD1956900F86E85 /* OutputShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OutputShader.cpp; sourceTree = "<group>"; };
|
||||
@ -1555,6 +1556,7 @@
|
||||
4B15AA0A2082C799005E6C8D /* Video.cpp */,
|
||||
4B15AA092082C799005E6C8D /* AppleII.hpp */,
|
||||
4B15AA0B2082C799005E6C8D /* Video.hpp */,
|
||||
4BC39565208EDFCE0044766B /* Card.hpp */,
|
||||
);
|
||||
path = AppleII;
|
||||
sourceTree = "<group>";
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "../../../../../Analyser/Static/Acorn/Target.hpp"
|
||||
#include "../../../../../Analyser/Static/AmstradCPC/Target.hpp"
|
||||
#include "../../../../../Analyser/Static/AppleII/Target.hpp"
|
||||
#include "../../../../../Analyser/Static/Commodore/Target.hpp"
|
||||
#include "../../../../../Analyser/Static/MSX/Target.hpp"
|
||||
#include "../../../../../Analyser/Static/Oric/Target.hpp"
|
||||
@ -156,7 +157,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
|
||||
- (instancetype)initWithAppleII {
|
||||
self = [super init];
|
||||
if(self) {
|
||||
using Target = Analyser::Static::Target;
|
||||
using Target = Analyser::Static::AppleII::Target;
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
target->machine = Analyser::Machine::AppleII;
|
||||
_targets.push_back(std::move(target));
|
||||
|
Loading…
Reference in New Issue
Block a user