1
0
mirror of https://github.com/TomHarte/CLK.git synced 2026-04-20 10:17:05 +00:00

Attempt support for C16 TAPs.

This commit is contained in:
Thomas Harte
2025-01-05 08:51:20 -05:00
parent f0711a9fbc
commit f66b6fc20c
3 changed files with 57 additions and 17 deletions
+1 -1
View File
@@ -234,7 +234,7 @@ public:
*value = io_direction_;
} else {
const uint8_t all_inputs =
(tape_player_->input() ? 0x00 : 0x10) |
(tape_player_->input() ? 0x10 : 0x00) |
(serial_port_.level(Serial::Line::Data) ? 0x80 : 0x00) |
(serial_port_.level(Serial::Line::Clock) ? 0x40 : 0x00);
*value =
+49 -15
View File
@@ -17,27 +17,50 @@ CommodoreTAP::CommodoreTAP(const std::string &file_name) : Tape(serialiser_), se
CommodoreTAP::Serialiser::Serialiser(const std::string &file_name) :
file_(file_name, FileHolder::FileMode::Read)
{
if(!file_.check_signature("C64-TAPE-RAW"))
const bool is_c64 = file_.check_signature("C64-TAPE-RAW");
file_.seek(0, SEEK_SET);
const bool is_c16 = file_.check_signature("C16-TAPE-RAW");
if(!is_c64 && !is_c16) {
throw ErrorNotCommodoreTAP;
// check the file version
switch(file_.get8()) {
case 0: updated_layout_ = false; break;
case 1: updated_layout_ = true; break;
default: throw ErrorNotCommodoreTAP;
}
// skip reserved bytes
file_.seek(3, SEEK_CUR);
// Get and check the file version.
version_ = file_.get8();
if(version_ > 2) {
throw ErrorNotCommodoreTAP;
}
// read file size
// Read clock rate-implying bytes.
enum Platform: uint8_t {
C64 = 0,
Vic20 = 1,
C16 = 2,
};
const auto platform = Platform(file_.get8());
enum VideoStandard: uint8_t {
PAL = 0,
NTSC1 = 1,
NTSC2 = 2,
};
const auto video = VideoStandard(file_.get8());
file_.seek(1, SEEK_CUR);
// Read file size.
file_size_ = file_.get32le();
// set up for pulse output at the PAL clock rate, with each high and
// Set up for pulse output at the requested clock rate, with each high and
// low being half of whatever length values will be read; pretend that
// a high pulse has just been distributed to imply that the next thing
// that needs to happen is a length check
current_pulse_.length.clock_rate = 985248 * 2;
// that needs to happen is a length check.
current_pulse_.length.clock_rate = static_cast<unsigned int>(
[&] {
switch(platform) {
case Vic20: return video == PAL ? 1'108'000 : 1'022'000; // TODO: these are inexact.
case C64: return video == PAL ? 985'248 : 1'022'727;
case C16: return video == PAL ? 886'722 : 894'886;
}
}() * (half_waves() ? 1 : 2)
);
current_pulse_.type = Pulse::High;
}
@@ -56,10 +79,10 @@ Storage::Tape::Pulse CommodoreTAP::Serialiser::next_pulse() {
return current_pulse_;
}
if(current_pulse_.type == Pulse::High) {
const auto read_next_length = [&]() -> bool {
uint32_t next_length;
const uint8_t next_byte = file_.get8();
if(!updated_layout_ || next_byte > 0) {
if(!updated_layout() || next_byte > 0) {
next_length = uint32_t(next_byte) << 3;
} else {
next_length = file_.get24le();
@@ -69,8 +92,19 @@ Storage::Tape::Pulse CommodoreTAP::Serialiser::next_pulse() {
is_at_end_ = true;
current_pulse_.length.length = current_pulse_.length.clock_rate;
current_pulse_.type = Pulse::Zero;
return false;
} else {
current_pulse_.length.length = next_length;
return true;
}
};
if(half_waves()) {
if(read_next_length()) {
current_pulse_.type = current_pulse_.type == Pulse::High ? Pulse::Low : Pulse::High;
}
} else if(current_pulse_.type == Pulse::High) {
if(read_next_length()) {
current_pulse_.type = Pulse::Low;
}
} else {
+7 -1
View File
@@ -43,8 +43,14 @@ private:
Storage::FileHolder file_;
bool updated_layout_;
uint32_t file_size_;
uint8_t version_;
bool updated_layout() const {
return version_ >= 1;
}
bool half_waves() const {
return version_ >= 2;
}
Pulse current_pulse_;
bool is_at_end_ = false;