diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index 4dd3d8d73..e011d7a9b 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -10,6 +10,7 @@ #include #include "../../../Storage/Tape/Formats/TapePRG.hpp" +#include "../../../Storage/Tape/Parsers/Commodore.hpp" #include "../../../StaticAnalyser/StaticAnalyser.hpp" using namespace Commodore::Vic20; @@ -127,7 +128,25 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin // CPU or 6560 costs. if(use_fast_tape_hack_ && tape_->has_tape() && operation == CPU6502::BusOperation::ReadOpcode) { if(address == 0xf7b2) { - printf("Find header\n"); + // Address 0xf7b2 contains a JSR to 0xf8c0 that will fill the tape buffer with the next header. + // So cancel that via a double NOP and fill in the next header programmatically. + Storage::Tape::Commodore::Parser parser; + std::unique_ptr header = parser.get_next_header(tape_->get_tape()); + + // serialise to wherever b2:b3 points + uint16_t tape_buffer_pointer = (uint16_t)user_basic_memory_[0xb2] | (uint16_t)(user_basic_memory_[0xb3] << 8); + if(header) { + header->serialise(&user_basic_memory_[tape_buffer_pointer], 0x8000 - tape_buffer_pointer); + } else { + // no header found, so store end-of-tape + user_basic_memory_[tape_buffer_pointer] = 0x05; // i.e. end of tape + } + + // clear status and the verify flag + user_basic_memory_[0x90] = 0; + user_basic_memory_[0x93] = 0; + + *value = 0x0c; // i.e. NOP abs } else if(address == 0xf90b) { printf("Tape receive\n"); } diff --git a/Storage/Tape/Parsers/Commodore.cpp b/Storage/Tape/Parsers/Commodore.cpp index 332550638..628ad823d 100644 --- a/Storage/Tape/Parsers/Commodore.cpp +++ b/Storage/Tape/Parsers/Commodore.cpp @@ -119,6 +119,20 @@ std::unique_ptr
Parser::get_next_header_body(const std::shared_ptr Parser::get_next_data_body(const std::shared_ptr &tape, bool is_original) { std::unique_ptr data(new Data); diff --git a/Storage/Tape/Parsers/Commodore.hpp b/Storage/Tape/Parsers/Commodore.hpp index ebde8066d..5b36a83c1 100644 --- a/Storage/Tape/Parsers/Commodore.hpp +++ b/Storage/Tape/Parsers/Commodore.hpp @@ -10,7 +10,6 @@ #define Storage_Tape_Parsers_Commodore_hpp #include "TapeParser.hpp" -//#include "Utilities.hpp" #include #include @@ -43,6 +42,12 @@ struct Header { uint16_t ending_address; bool parity_was_valid; bool duplicate_matched; + + /*! + Writes a byte serialised version of this header to @c target, writing at most + @c length bytes. + */ + void serialise(uint8_t *target, uint16_t length); }; struct Data {