1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-04 18:29:40 +00:00

Implemented speedy header finding. So that's half of it.

This commit is contained in:
Thomas Harte 2017-05-07 20:32:48 -04:00
parent 0771363f3b
commit 2807e3134f
3 changed files with 40 additions and 2 deletions

View File

@ -10,6 +10,7 @@
#include <algorithm>
#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<Storage::Tape::Commodore::Header> 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");
}

View File

@ -119,6 +119,20 @@ std::unique_ptr<Header> Parser::get_next_header_body(const std::shared_ptr<Stora
return header;
}
void Header::serialise(uint8_t *target, uint16_t length) {
switch(type)
{
default: target[0] = 0xff; break;
case Header::RelocatableProgram: target[0] = 0x01; break;
case Header::DataBlock: target[0] = 0x02; break;
case Header::NonRelocatableProgram: target[0] = 0x03; break;
case Header::DataSequenceHeader: target[0] = 0x04; break;
case Header::EndOfTape: target[0] = 0x05; break;
}
memcpy(&target[1], data.data(), 191);
}
std::unique_ptr<Data> Parser::get_next_data_body(const std::shared_ptr<Storage::Tape::Tape> &tape, bool is_original)
{
std::unique_ptr<Data> data(new Data);

View File

@ -10,7 +10,6 @@
#define Storage_Tape_Parsers_Commodore_hpp
#include "TapeParser.hpp"
//#include "Utilities.hpp"
#include <memory>
#include <string>
@ -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 {