mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Start wiring in a floppy controller.
This commit is contained in:
parent
547dc29a60
commit
d2b077c573
@ -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 {
|
||||
|
42
Machines/Acorn/Archimedes/FloppyDisc.hpp
Normal file
42
Machines/Acorn/Archimedes/FloppyDisc.hpp
Normal 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_;
|
||||
};
|
||||
|
||||
}
|
@ -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_;
|
||||
|
@ -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(); }
|
||||
|
@ -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 */,
|
||||
|
Loading…
x
Reference in New Issue
Block a user