1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-09 01:29:44 +00:00

Start wiring in a floppy controller.

This commit is contained in:
Thomas Harte 2024-04-07 21:22:35 -04:00
parent 547dc29a60
commit d2b077c573
5 changed files with 108 additions and 30 deletions

View File

@ -346,22 +346,28 @@ class ConcreteMachine:
//
// * CPU: 24;
// * video: 24 / video_divider;
// * floppy: 8;
// * timers: 2;
// * sound: 1.
tick_cpu_video<0, video_divider>(); tick_cpu_video<1, video_divider>();
tick_cpu_video<2, video_divider>(); tick_cpu_video<3, video_divider>();
tick_cpu_video<4, video_divider>(); tick_cpu_video<5, video_divider>();
tick_cpu_video<2, video_divider>(); tick_floppy();
tick_cpu_video<3, video_divider>(); tick_cpu_video<4, video_divider>();
tick_cpu_video<5, video_divider>(); tick_floppy();
tick_cpu_video<6, video_divider>(); tick_cpu_video<7, video_divider>();
tick_cpu_video<8, video_divider>(); tick_cpu_video<9, video_divider>();
tick_cpu_video<10, video_divider>(); tick_cpu_video<11, video_divider>();
tick_cpu_video<8, video_divider>(); tick_floppy();
tick_cpu_video<9, video_divider>(); tick_cpu_video<10, video_divider>();
tick_cpu_video<11, video_divider>(); tick_floppy();
tick_timers();
tick_cpu_video<12, video_divider>(); tick_cpu_video<13, video_divider>();
tick_cpu_video<14, video_divider>(); tick_cpu_video<15, video_divider>();
tick_cpu_video<16, video_divider>(); tick_cpu_video<17, video_divider>();
tick_cpu_video<14, video_divider>(); tick_floppy();
tick_cpu_video<15, video_divider>(); tick_cpu_video<16, video_divider>();
tick_cpu_video<17, video_divider>(); tick_floppy();
tick_cpu_video<18, video_divider>(); tick_cpu_video<19, video_divider>();
tick_cpu_video<20, video_divider>(); tick_cpu_video<21, video_divider>();
tick_cpu_video<20, video_divider>(); tick_floppy();
tick_cpu_video<21, video_divider>(); tick_cpu_video<22, video_divider>();
tick_cpu_video<23, video_divider>(); tick_floppy();
tick_timers();
tick_sound();
}
@ -457,6 +463,7 @@ class ConcreteMachine:
void tick_timers() { executor_.bus.tick_timers(); }
void tick_sound() { executor_.bus.sound().tick(); }
void tick_video() { executor_.bus.video().tick(); }
void tick_floppy() { executor_.bus.tick_floppy(); }
// MARK: - MediaTarget
bool insert_media(const Analyser::Static::Media &) override {

View File

@ -0,0 +1,42 @@
//
// FloppyDisc.hpp
// Clock Signal
//
// Created by Thomas Harte on 07/04/2024.
// Copyright © 2024 Thomas Harte. All rights reserved.
//
#pragma once
#include "../../../Components/1770/1770.hpp"
namespace Archimedes {
template <typename InterruptObserverT>
class FloppyDisc: public WD::WD1770, public WD::WD1770::Delegate {
public:
FloppyDisc(InterruptObserverT &observer) : WD::WD1770(P1772), observer_(observer) {
emplace_drives(1, 8000000, 300, 2);
set_delegate(this);
}
void wd1770_did_change_output(WD::WD1770 *) override {
observer_.update_interrupts();
}
void set_control(uint8_t value) {
// TODO:
// b0, b1, b2, b3 = drive selects;
// b4 = side select;
// b5 = motor on/off
// b6 = floppy in use (i.e. LED?);
// b7 = disc eject/change reset.
get_drive().set_head(1 ^ ((value >> 4) & 1));
}
void reset() {}
private:
InterruptObserverT &observer_;
};
}

View File

@ -9,6 +9,7 @@
#pragma once
#include "CMOSRAM.hpp"
#include "FloppyDisc.hpp"
#include "Keyboard.hpp"
#include "Sound.hpp"
#include "Video.hpp"
@ -20,7 +21,6 @@ namespace Archimedes {
// IRQ A flags
namespace IRQA {
// The first four of these are taken from the A500 documentation and may be inaccurate.
static constexpr uint8_t PrinterBusy = 0x01;
static constexpr uint8_t SerialRinging = 0x02;
static constexpr uint8_t PrinterAcknowledge = 0x04;
@ -28,17 +28,16 @@ namespace IRQA {
static constexpr uint8_t PowerOnReset = 0x10;
static constexpr uint8_t Timer0 = 0x20;
static constexpr uint8_t Timer1 = 0x40;
static constexpr uint8_t SetAlways = 0x80;
static constexpr uint8_t Force = 0x80;
}
// IRQ B flags
namespace IRQB {
// These are taken from the A3010 documentation.
static constexpr uint8_t PoduleFIQRequest = 0x01;
static constexpr uint8_t SoundBufferPointerUsed = 0x02;
static constexpr uint8_t SerialLine = 0x04;
static constexpr uint8_t IDE = 0x08;
static constexpr uint8_t FloppyDiscInterrupt = 0x10;
static constexpr uint8_t FloppyDiscChanged = 0x10;
static constexpr uint8_t PoduleIRQRequest = 0x20;
static constexpr uint8_t KeyboardTransmitEmpty = 0x40;
static constexpr uint8_t KeyboardReceiveFull = 0x80;
@ -46,11 +45,11 @@ namespace IRQB {
// FIQ flags
namespace FIQ {
// These are taken from the A3010 documentation.
static constexpr uint8_t FloppyDiscData = 0x01;
static constexpr uint8_t SerialLine = 0x10;
static constexpr uint8_t FloppyDiscInterrupt = 0x02;
static constexpr uint8_t Econet = 0x04;
static constexpr uint8_t PoduleFIQRequest = 0x40;
static constexpr uint8_t SetAlways = 0x80;
static constexpr uint8_t Force = 0x80;
}
namespace InterruptRequests {
@ -113,6 +112,10 @@ struct InputOutputController {
}
}
void tick_floppy() {
floppy_.run_for(Cycles(1));
}
/// Decomposes an Archimedes bus address into bank, offset and type.
struct Address {
constexpr Address(uint32_t bus_address) noexcept {
@ -240,6 +243,12 @@ struct InputOutputController {
break;
}
break;
// Bank 1: the floppy disc controller.
case 1:
set_byte(floppy_.read(target.offset >> 2));
// logger.error().append("Floppy read; offset %02x", target.offset);
break;
}
return true;
@ -344,6 +353,13 @@ struct InputOutputController {
}
break;
// Bank 1: the floppy disc controller.
case 1:
// logger.error().append("Floppy write; %02x to offset %02x", bus_value, target.offset);
floppy_.write(target.offset >> 2, byte(bus_value));
// set_byte(floppy_.read(target.offset >> 2));
break;
// Bank 5: both the hard disk and the latches, depending on type.
case 5:
switch(target.type) {
@ -361,7 +377,7 @@ struct InputOutputController {
logger.error().append("TODO: printer data write; %02x", byte(bus_value));
break;
case 0x18:
case 0x18: {
// TODO, per the A500 documentation:
//
// Latch B:
@ -372,23 +388,17 @@ struct InputOutputController {
// b4: printer strobe
// b5: ?
// b6: ?
// b7: HS3?
// b7: Head select 3?
const uint8_t value = byte(bus_value);
logger.error().append("TODO: latch B write; %02x", byte(bus_value));
break;
floppy_.set_is_double_density(!(value & 0x2));
if(value & 0x08) floppy_.reset();
// logger.error().append("TODO: latch B write; %02x", byte(bus_value));
} break;
case 0x40: {
// TODO, per the A500 documentation:
//
// Latch A:
// b0, b1, b2, b3 = drive selects;
// b4 = side select;
// b5 = motor on/off
// b6 = floppy in use (i.e. LED?);
// b7 = "Not used."
const uint8_t value = byte(bus_value);
// logger.error().append("TODO: latch A write; %02x", value);
floppy_.set_control(value);
// Set the floppy indicator on if any drive is selected,
// because this emulator is compressing them all into a
@ -445,12 +455,13 @@ struct InputOutputController {
InputOutputController(InterruptObserverT &observer, ClockRateObserverT &clock_observer, const uint8_t *ram) :
observer_(observer),
keyboard_(serial_),
floppy_(*this),
sound_(*this, ram),
video_(*this, clock_observer, sound_, ram)
{
irq_a_.status = IRQA::SetAlways | IRQA::PowerOnReset;
irq_a_.status = IRQA::Force | IRQA::PowerOnReset;
irq_b_.status = 0x00;
fiq_.status = FIQ::SetAlways;
fiq_.status = FIQ::Force;
i2c_.add_peripheral(&cmos_, 0xa0);
update_interrupts();
@ -474,6 +485,18 @@ struct InputOutputController {
irq_a_.set(IRQA::VerticalFlyback);
}
// if(floppy_.get_interrupt_request_line()) {
// irq_b_.set(FIQ::FloppyDiscInterrupt);
// } else {
// irq_b_.clear(FIQ::FloppyDiscInterrupt);
// }
//
// if(floppy_.get_data_request_line()) {
// irq_b_.set(FIQ::FloppyDiscData);
// } else {
// irq_b_.clear(FIQ::FloppyDiscData);
// }
observer_.update_interrupts();
}
@ -521,6 +544,9 @@ private:
// The control register.
uint8_t control_ = 0xff;
// The floppy disc interface.
FloppyDisc<InputOutputController> floppy_;
// The I2C bus.
I2C::Bus i2c_;
CMOSRAM cmos_;

View File

@ -198,6 +198,7 @@ struct MemoryController {
// Expose various IOC-owned things.
//
void tick_timers() { ioc_.tick_timers(); }
void tick_floppy() { ioc_.tick_floppy(); }
auto &sound() { return ioc_.sound(); }
const auto &sound() const { return ioc_.sound(); }

View File

@ -1816,6 +1816,7 @@
4BAB1E592BAB5CB90002C9B9 /* CMOSRAM.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CMOSRAM.hpp; sourceTree = "<group>"; };
4BAB1E5A2BAB5F400002C9B9 /* InputOutputController.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = InputOutputController.hpp; sourceTree = "<group>"; };
4BAB1E5B2BAF59CB0002C9B9 /* KeyboardMapper.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = KeyboardMapper.hpp; sourceTree = "<group>"; };
4BAB1E5C2BC3727C0002C9B9 /* FloppyDisc.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = FloppyDisc.hpp; sourceTree = "<group>"; };
4BAB62AC1D3272D200DF5BA0 /* Disk.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Disk.hpp; sourceTree = "<group>"; };
4BAB62AE1D32730D00DF5BA0 /* Storage.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Storage.hpp; sourceTree = "<group>"; };
4BAF2B4C2004580C00480230 /* DMK.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DMK.cpp; sourceTree = "<group>"; };
@ -4403,6 +4404,7 @@
4BB505842B9634F30031C43C /* Archimedes.cpp */,
4BB505852B9634F30031C43C /* Archimedes.hpp */,
4BAB1E592BAB5CB90002C9B9 /* CMOSRAM.hpp */,
4BAB1E5C2BC3727C0002C9B9 /* FloppyDisc.hpp */,
4BAB1E552BAB5B6D0002C9B9 /* HalfDuplexSerial.hpp */,
4BAB1E5A2BAB5F400002C9B9 /* InputOutputController.hpp */,
4BAB1E542BAB5B3F0002C9B9 /* Keyboard.hpp */,