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:
@@ -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 =
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user