From a482ce1546c46cb711041e95a361d856823cd016 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 19 Mar 2021 11:12:50 -0400 Subject: [PATCH] Adds a tape player. --- Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp | 34 ++++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp b/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp index d1c84ed27..daa3c751f 100644 --- a/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp +++ b/Machines/Sinclair/ZXSpectrum/ZXSpectrum.cpp @@ -41,6 +41,7 @@ using Model = Analyser::Static::ZXSpectrum::Target::Model; template class ConcreteMachine: public Machine, public MachineTypes::MappedKeyboardMachine, + public MachineTypes::MediaTarget, public MachineTypes::ScanProducer, public MachineTypes::TimedMachine, public CPU::Z80::BusHandler { @@ -52,7 +53,8 @@ template class ConcreteMachine: mixer_(ay_, audio_toggle_), speaker_(mixer_), keyboard_(Sinclair::ZX::Keyboard::Machine::ZXSpectrum), - keyboard_mapper_(Sinclair::ZX::Keyboard::Machine::ZXSpectrum) + keyboard_mapper_(Sinclair::ZX::Keyboard::Machine::ZXSpectrum), + tape_player_(clock_rate() * 2) { set_clock_rate(clock_rate()); speaker_.set_input_rate(float(clock_rate()) / 2.0f); @@ -68,8 +70,11 @@ template class ConcreteMachine: update_memory_map(); Memory::Fuzz(ram_); - // TODO: insert media. - (void)target; + // Insert media. + insert_media(target.media); + + // TODO: intelligent motor control (?) + tape_player_.set_motor_control(true); } ~ConcreteMachine() { @@ -199,11 +204,14 @@ template class ConcreteMachine: *cycle.value = 0xff; if(!(address&1)) { - *cycle.value &= keyboard_.read(address); - + // Port FE: + // // address b8+: mask of keyboard lines to select // result: b0–b4: mask of keys pressed // b6: tape input + + *cycle.value &= keyboard_.read(address); + *cycle.value &= tape_player_.get_input() ? 0xbf : 0xff; } switch(address) { @@ -232,6 +240,9 @@ template class ConcreteMachine: if(video_.did_flush()) { z80_.set_interrupt_line(video_.last_valid()->get_interrupt_line()); } + + // TODO: sleeping support here. + tape_player_.run_for(duration.as_integral()); } public: @@ -258,6 +269,16 @@ template class ConcreteMachine: keyboard_.clear_all_keys(); } + // MARK: - MediaTarget. + bool insert_media(const Analyser::Static::Media &media) override { + // If there are any tapes supplied, use the first of them. + if(!media.tapes.empty()) { + tape_player_.set_tape(media.tapes.front()); + } + + return !media.tapes.empty(); + } + private: CPU::Z80::Processor z80_; @@ -357,6 +378,9 @@ template class ConcreteMachine: // MARK: - Keyboard. Sinclair::ZX::Keyboard::Keyboard keyboard_; Sinclair::ZX::Keyboard::KeyboardMapper keyboard_mapper_; + + // MARK: - Tape and disc. + Storage::Tape::BinaryTapePlayer tape_player_; };