mirror of
https://github.com/TomHarte/CLK.git
synced 2024-10-01 13:58:20 +00:00
Makes some sort of first attempt at having the IWM read.
This commit is contained in:
parent
833258f3d7
commit
a413ae11cb
@ -59,8 +59,12 @@ uint8_t IWM::read(int address) {
|
|||||||
return 0xff;
|
return 0xff;
|
||||||
|
|
||||||
case ENABLE: /* Read data register. */
|
case ENABLE: /* Read data register. */
|
||||||
|
if(data_register_ & 0x80) {
|
||||||
|
printf("[%02x] ", data_register_);
|
||||||
|
data_register_ = 0;
|
||||||
|
}
|
||||||
printf("Reading data register\n");
|
printf("Reading data register\n");
|
||||||
return 0x00;
|
return data_register_;
|
||||||
|
|
||||||
case Q6: case Q6|ENABLE: {
|
case Q6: case Q6|ENABLE: {
|
||||||
/*
|
/*
|
||||||
@ -257,11 +261,49 @@ void IWM::run_for(const Cycles cycles) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Activity otherwise depends on mode and motor state.
|
// Activity otherwise depends on mode and motor state.
|
||||||
|
const bool run_disk = drive_motor_on_ && drives_[active_drive_];
|
||||||
|
int integer_cycles = cycles.as_int();
|
||||||
switch(state_ & (Q6 | Q7 | ENABLE)) {
|
switch(state_ & (Q6 | Q7 | ENABLE)) {
|
||||||
|
case ENABLE: // i.e. read mode.
|
||||||
|
while(integer_cycles--) {
|
||||||
|
if(run_disk) {
|
||||||
|
drives_[active_drive_]->run_for(Cycles(1));
|
||||||
|
}
|
||||||
|
++cycles_since_shift_;
|
||||||
|
if(cycles_since_shift_ == bit_length_ + Cycles(2)) {
|
||||||
|
propose_shift(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if(run_disk) drives_[active_drive_]->run_for(cycles);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IWM::process_event(const Storage::Disk::Track::Event &event) {
|
||||||
|
switch(event.type) {
|
||||||
|
case Storage::Disk::Track::Event::IndexHole: return;
|
||||||
|
case Storage::Disk::Track::Event::FluxTransition:
|
||||||
|
propose_shift(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IWM::propose_shift(uint8_t bit) {
|
||||||
|
// TODO: synchronous mode.
|
||||||
|
shift_register_ = uint8_t((shift_register_ << 1) | bit);
|
||||||
|
if(shift_register_ & 0x80) {
|
||||||
|
printf("%02x -> data\n", shift_register_);
|
||||||
|
data_register_ = shift_register_;
|
||||||
|
shift_register_ = 0;
|
||||||
|
}
|
||||||
|
cycles_since_shift_ = Cycles(0);
|
||||||
|
}
|
||||||
|
|
||||||
void IWM::set_drive(int slot, Storage::Disk::Drive *drive) {
|
void IWM::set_drive(int slot, Storage::Disk::Drive *drive) {
|
||||||
drives_[slot] = drive;
|
drives_[slot] = drive;
|
||||||
|
drive->set_event_delegate(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
namespace Apple {
|
namespace Apple {
|
||||||
|
|
||||||
class IWM {
|
class IWM:
|
||||||
|
public Storage::Disk::Drive::EventDelegate {
|
||||||
public:
|
public:
|
||||||
IWM(int clock_rate);
|
IWM(int clock_rate);
|
||||||
|
|
||||||
@ -42,8 +43,12 @@ class IWM {
|
|||||||
void set_drive(int slot, Storage::Disk::Drive *drive);
|
void set_drive(int slot, Storage::Disk::Drive *drive);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Storage::Disk::Drive::EventDelegate.
|
||||||
|
void process_event(const Storage::Disk::Track::Event &event) override;
|
||||||
|
|
||||||
const int clock_rate_;
|
const int clock_rate_;
|
||||||
|
|
||||||
|
uint8_t data_register_ = 0;
|
||||||
uint8_t mode_ = 0;
|
uint8_t mode_ = 0;
|
||||||
bool read_write_ready_ = true;
|
bool read_write_ready_ = true;
|
||||||
bool write_overran_ = false;
|
bool write_overran_ = false;
|
||||||
@ -58,6 +63,9 @@ class IWM {
|
|||||||
|
|
||||||
void access(int address);
|
void access(int address);
|
||||||
|
|
||||||
|
uint8_t shift_register_ = 0;
|
||||||
|
void propose_shift(uint8_t bit);
|
||||||
|
Cycles cycles_since_shift_;
|
||||||
Cycles bit_length_;
|
Cycles bit_length_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "Video.hpp"
|
#include "Video.hpp"
|
||||||
|
|
||||||
#include "../../CRTMachine.hpp"
|
#include "../../CRTMachine.hpp"
|
||||||
|
#include "../../MediaTarget.hpp"
|
||||||
|
|
||||||
//#define LOG_TRACE
|
//#define LOG_TRACE
|
||||||
|
|
||||||
@ -41,9 +42,12 @@ namespace Macintosh {
|
|||||||
template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachine:
|
template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachine:
|
||||||
public Machine,
|
public Machine,
|
||||||
public CRTMachine::Machine,
|
public CRTMachine::Machine,
|
||||||
|
public MediaTarget::Machine,
|
||||||
public CPU::MC68000::BusHandler {
|
public CPU::MC68000::BusHandler {
|
||||||
public:
|
public:
|
||||||
ConcreteMachine(const ROMMachine::ROMFetcher &rom_fetcher) :
|
using Target = Analyser::Static::Macintosh::Target;
|
||||||
|
|
||||||
|
ConcreteMachine(const Target &target, const ROMMachine::ROMFetcher &rom_fetcher) :
|
||||||
mc68000_(*this),
|
mc68000_(*this),
|
||||||
iwm_(CLOCK_RATE),
|
iwm_(CLOCK_RATE),
|
||||||
video_(ram_, audio_, drive_speed_accumulator_),
|
video_(ram_, audio_, drive_speed_accumulator_),
|
||||||
@ -97,6 +101,9 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
|||||||
// The Mac runs at 7.8336mHz.
|
// The Mac runs at 7.8336mHz.
|
||||||
set_clock_rate(double(CLOCK_RATE));
|
set_clock_rate(double(CLOCK_RATE));
|
||||||
audio_.speaker.set_input_rate(float(CLOCK_RATE));
|
audio_.speaker.set_input_rate(float(CLOCK_RATE));
|
||||||
|
|
||||||
|
// Insert any supplied media.
|
||||||
|
insert_media(target.media);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ConcreteMachine() {
|
~ConcreteMachine() {
|
||||||
@ -312,6 +319,18 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
|||||||
video_.set_use_alternate_buffers(use_alternate_screen_buffer, use_alternate_audio_buffer);
|
video_.set_use_alternate_buffers(use_alternate_screen_buffer, use_alternate_audio_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool insert_media(const Analyser::Static::Media &media) override {
|
||||||
|
if(media.disks.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// TODO: shouldn't allow disks to be replaced like this, as the Mac
|
||||||
|
// uses software eject. Will need to expand messaging ability of
|
||||||
|
// insert_media.
|
||||||
|
drives_[0].set_disk(media.disks[0]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct IWM {
|
struct IWM {
|
||||||
IWM(int clock_rate) : iwm(clock_rate) {}
|
IWM(int clock_rate) : iwm(clock_rate) {}
|
||||||
@ -465,10 +484,10 @@ Machine *Machine::Macintosh(const Analyser::Static::Target *target, const ROMMac
|
|||||||
using Model = Analyser::Static::Macintosh::Target::Model;
|
using Model = Analyser::Static::Macintosh::Target::Model;
|
||||||
switch(mac_target->model) {
|
switch(mac_target->model) {
|
||||||
default:
|
default:
|
||||||
case Model::Mac128k: return new ConcreteMachine<Model::Mac128k>(rom_fetcher);
|
case Model::Mac128k: return new ConcreteMachine<Model::Mac128k>(*mac_target, rom_fetcher);
|
||||||
case Model::Mac512k: return new ConcreteMachine<Model::Mac512k>(rom_fetcher);
|
case Model::Mac512k: return new ConcreteMachine<Model::Mac512k>(*mac_target, rom_fetcher);
|
||||||
case Model::Mac512ke: return new ConcreteMachine<Model::Mac512ke>(rom_fetcher);
|
case Model::Mac512ke: return new ConcreteMachine<Model::Mac512ke>(*mac_target, rom_fetcher);
|
||||||
case Model::MacPlus: return new ConcreteMachine<Model::MacPlus>(rom_fetcher);
|
case Model::MacPlus: return new ConcreteMachine<Model::MacPlus>(*mac_target, rom_fetcher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,12 @@
|
|||||||
using namespace Apple::Macintosh;
|
using namespace Apple::Macintosh;
|
||||||
|
|
||||||
SonyDrive::SonyDrive(int input_clock_rate, bool is_800k) :
|
SonyDrive::SonyDrive(int input_clock_rate, bool is_800k) :
|
||||||
Storage::Disk::Drive(static_cast<unsigned int>(input_clock_rate), is_800k ? 2 : 1), is_800k_(is_800k) {}
|
Storage::Disk::Drive(static_cast<unsigned int>(input_clock_rate), is_800k ? 2 : 1), is_800k_(is_800k) {
|
||||||
|
// Start with a valid rotation speed.
|
||||||
|
if(is_800k) {
|
||||||
|
set_rotation_speed(393.3807f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SonyDrive::did_step(Storage::Disk::HeadPosition to_position) {
|
void SonyDrive::did_step(Storage::Disk::HeadPosition to_position) {
|
||||||
// The 800kb drive automatically selects rotation speed as a function of
|
// The 800kb drive automatically selects rotation speed as a function of
|
||||||
|
Loading…
Reference in New Issue
Block a user