diff --git a/Machines/Commodore/Plus4/Keyboard.cpp b/Machines/Commodore/Plus4/Keyboard.cpp index 871422a75..1158c25b2 100644 --- a/Machines/Commodore/Plus4/Keyboard.cpp +++ b/Machines/Commodore/Plus4/Keyboard.cpp @@ -46,13 +46,13 @@ uint16_t KeyboardMapper::mapped_key_for_key(Inputs::Keyboard::Key key) const { BIND(OpenSquareBracket, At); BIND(CloseSquareBracket, Plus); BIND(Backslash, Clear_Home); + BIND(BackTick, Asterisk); BIND(F11, Clear_Home); BIND(F12, Run_Stop); // TODO: // GBP - // Asterisk } #undef BIND return MachineTypes::MappedKeyboardMachine::KeyNotMapped; diff --git a/Machines/Commodore/Plus4/Plus4.cpp b/Machines/Commodore/Plus4/Plus4.cpp index 2041d2fd3..24343474e 100644 --- a/Machines/Commodore/Plus4/Plus4.cpp +++ b/Machines/Commodore/Plus4/Plus4.cpp @@ -113,10 +113,12 @@ public: m6502_(*this), interrupts_(*this), timers_(interrupts_), - video_(video_map_, interrupts_), - tape_player_(1'000'000) + video_(video_map_, interrupts_) { - set_clock_rate(clock_rate(false)); + const auto clock = clock_rate(false); + media_divider_ = Cycles(clock); + set_clock_rate(clock); + tape_player_ = std::make_unique(clock); const auto kernel = ROM::Name::Plus4KernelPALv5; const auto basic = ROM::Name::Plus4BASIC; @@ -137,6 +139,7 @@ public: video_map_.page(ram_.data()); insert_media(target.media); + printf("Loading command is: %s\n", target.loading_command.c_str()); } Cycles perform_bus_operation( @@ -154,6 +157,7 @@ public: timers_.tick(timers_cycles.as()); video_.run_for(length); + tape_player_->run_for(length); if(operation == CPU::MOS6502::BusOperation::Ready) { return length; @@ -171,6 +175,30 @@ public: // b2 = serial ATN out; // b1 = serial clock out and cassette write; // b0 = serial data out. + + if(isReadOperation(operation)) { + if(address) { + *value = io_direction_; +// printf("Read data direction: %02x\n", *value); + } else { + const uint8_t all_inputs = tape_player_->input() ? 0x10 : 0x00; + *value = + (io_direction_ & io_output_) | + (~io_direction_ & all_inputs); + printf("Read input: %02x\n", *value); + } + } else { + if(address) { + io_direction_ = *value; +// printf("Set data direction: %02x\n", *value); + } else { + io_output_ = *value; + printf("Output: %02x\n", *value); + tape_player_->set_motor_control(!(*value & 0x08)); +// tape_player_->set_motor_control(*value & 0x08); + } + } + // printf("%04x: %02x %c\n", address, *value, isReadOperation(operation) ? 'r' : 'w'); } else if(address < 0xfd00 || address >= 0xff40) { if(isReadOperation(operation)) { @@ -334,7 +362,11 @@ private: m6502_.run_for(cycles); } - bool insert_media(const Analyser::Static::Media &) final { + bool insert_media(const Analyser::Static::Media &media) final { + if(!media.tapes.empty()) { + tape_player_->set_tape(media.tapes[0]); + } + return true; } @@ -367,7 +399,9 @@ private: std::array key_states_{}; uint8_t keyboard_latch_ = 0xff; - Storage::Tape::BinaryTapePlayer tape_player_; + Cycles media_divider_; + std::unique_ptr tape_player_; + uint8_t io_direction_ = 0x00, io_output_ = 0x00; }; } diff --git a/Machines/Commodore/Plus4/Video.hpp b/Machines/Commodore/Plus4/Video.hpp index 2ccc7c6f2..300737b61 100644 --- a/Machines/Commodore/Plus4/Video.hpp +++ b/Machines/Commodore/Plus4/Video.hpp @@ -18,7 +18,7 @@ namespace Commodore::Plus4 { -constexpr double clock_rate(bool is_ntsc) { +constexpr int clock_rate(bool is_ntsc) { return is_ntsc ? 14'318'180 : // i.e. colour subcarrier * 4. 17'734'448; // i.e. very close to colour subcarrier * 4 — only about 0.1% off.