Skip to content

Commit

Permalink
Add support for WRITE FILEMARKS(16)
Browse files Browse the repository at this point in the history
  • Loading branch information
uweseimet committed Dec 9, 2024
1 parent 77a5968 commit 69c59b5
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 10 deletions.
30 changes: 26 additions & 4 deletions cpp/devices/tape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ bool Tape::SetUp()
{
WriteFilemarks6();
});
AddCommand(scsi_command::write_filemarks_16, [this]
{
WriteFilemarks(true);
});
AddCommand(scsi_command::locate_10, [this]
{
Locate(false);
Expand Down Expand Up @@ -461,9 +465,14 @@ void Tape::Space6()
}

void Tape::WriteFilemarks6()
{
WriteFilemarks(false);
}

void Tape::WriteFilemarks(bool write_filemarks_16)
{
if (tar_file) {
LogTrace("Writing filemarks in tar-compatibility mode is not supported, WRITE FILEMARKS(6) command is ignored");
LogTrace("Writing filemarks in tar-compatibility mode is not supported, WRITE FILEMARKS command is ignored");
StatusPhase();
return;
}
Expand All @@ -475,21 +484,34 @@ void Tape::WriteFilemarks6()

CheckWritePreconditions();

for (int i = 0; i < GetCdbInt24(2); i++) {
int count;
if (write_filemarks_16) {
if (const auto identifier = static_cast<uint32_t>(GetCdbInt64(4)); identifier) {
ResetPositions();
FindObject(identifier);
}

count = GetCdbInt24(12);
}
else {
count = GetCdbInt24(2);
}

for (int i = 0; i < count; i++) {
WriteMetaData(object_type::filemark);
}

StatusPhase();
}

void Tape::Locate(bool locate16)
void Tape::Locate(bool locate_16)
{
// CP is not supported
if (GetCdbByte(1) & 0x02) {
throw scsi_exception(sense_key::illegal_request, asc::invalid_field_in_cdb);
}

auto identifier = static_cast<uint32_t>(locate16 ? GetCdbInt64(4) : GetCdbInt32(3));
auto identifier = static_cast<uint32_t>(locate_16 ? GetCdbInt64(4) : GetCdbInt32(3));
const bool bt = GetCdbByte(1) & 0x04;

if (tar_file) {
Expand Down
1 change: 1 addition & 0 deletions cpp/devices/tape.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class Tape : public StorageDevice, public ScsiStreamCommands
void Rewind() override;
void Space6() override;
void WriteFilemarks6() override;
void WriteFilemarks(bool);
void FormatMedium();
void ReadPosition() const;
void Locate(bool);
Expand Down
1 change: 1 addition & 0 deletions cpp/shared/command_meta_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ CommandMetaData::CommandMetaData()
AddCommand(scsi_command::read_toc, 10, "READ TOC");
AddCommand(scsi_command::mode_select_10, 10, "MODE SELECT(10)");
AddCommand(scsi_command::mode_sense_10, 10, "MODE SENSE(10)");
AddCommand(scsi_command::write_filemarks_16, 16, "WRITE FILEMARKS(16)");
AddCommand(scsi_command::read_16, 16, "READ(16)");
AddCommand(scsi_command::write_16, 16, "WRITE(16)");
AddCommand(scsi_command::verify_16, 16, "VERIFY(16)");
Expand Down
1 change: 1 addition & 0 deletions cpp/shared/scsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ enum class scsi_command
read_toc = 0x43,
mode_select_10 = 0x55,
mode_sense_10 = 0x5a,
write_filemarks_16 = 0x80,
read_16 = 0x88,
write_16 = 0x8a,
verify_16 = 0x8f,
Expand Down
3 changes: 2 additions & 1 deletion cpp/test/command_meta_data_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ TEST(CommandMetaDataTest, GetCommandBytesCount)
EXPECT_EQ(10, meta_data.GetCommandBytesCount(scsi_command::read_toc));
EXPECT_EQ(10, meta_data.GetCommandBytesCount(scsi_command::mode_select_10));
EXPECT_EQ(10, meta_data.GetCommandBytesCount(scsi_command::mode_sense_10));
EXPECT_EQ(16, meta_data.GetCommandBytesCount(scsi_command::write_filemarks_16));
EXPECT_EQ(16, meta_data.GetCommandBytesCount(scsi_command::read_16));
EXPECT_EQ(16, meta_data.GetCommandBytesCount(scsi_command::write_16));
EXPECT_EQ(16, meta_data.GetCommandBytesCount(scsi_command::verify_16));
Expand All @@ -77,7 +78,7 @@ TEST(CommandMetaDataTest, GetCommandBytesCount)
++command_count;
}
}
EXPECT_EQ(48, command_count);
EXPECT_EQ(49, command_count);
}

TEST(CommandMetaDataTest, LogCdb)
Expand Down
4 changes: 3 additions & 1 deletion cpp/test/mocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,10 @@ class MockAbstractController : public AbstractController // NOSONAR Having many
FRIEND_TEST(TapeTest, Rewind);
FRIEND_TEST(TapeTest, Space6_simh);
FRIEND_TEST(TapeTest, Space6_tar);
FRIEND_TEST(TapeTest, WriteFileMarks6_simh);
FRIEND_TEST(TapeTest, WriteFileMarks6_tar);
FRIEND_TEST(TapeTest, WriteFileMarks6_simh);
FRIEND_TEST(TapeTest, WriteFileMarks16_tar);
FRIEND_TEST(TapeTest, WriteFileMarks16_simh);
FRIEND_TEST(TapeTest, FormatMedium_simh);
FRIEND_TEST(TapeTest, FormatMedium_tar);
FRIEND_TEST(TapeTest, Locate10_simh);
Expand Down
37 changes: 33 additions & 4 deletions cpp/test/tape_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -687,17 +687,17 @@ TEST(TapeTest, WriteFileMarks6_simh)
controller->SetCdbByte(1, 0b010);
Dispatch(tape, scsi_command::write_filemarks_6, sense_key::illegal_request, asc::invalid_field_in_cdb);

// Count = 0
// 0 filemarks
controller->SetCdbByte(1, 0b001);
EXPECT_NO_THROW(Dispatch(tape, scsi_command::write_filemarks_6));

// Count = 100
// 100 filemarks
controller->SetCdbByte(1, 0b001);
controller->SetCdbByte(4, 100);
EXPECT_NO_THROW(Dispatch(tape, scsi_command::write_filemarks_6));
CheckPositions(tape, 400, 0);

// Count = 100
// 100 filemarks
controller->SetCdbByte(1, 0b001);
controller->SetCdbByte(4, 100);
Dispatch(tape, scsi_command::write_filemarks_6, sense_key::volume_overflow);
Expand All @@ -713,10 +713,39 @@ TEST(TapeTest, WriteFileMarks6_tar)
auto [controller, tape] = CreateTape();
CreateImageFile(*tape, 512, "tar");

controller->SetCdbByte(1, 0b001);
EXPECT_NO_THROW(Dispatch(tape, scsi_command::write_filemarks_6));
}

TEST(TapeTest, WriteFileMarks16_simh)
{
auto [controller, tape] = CreateTape();
CreateImageFile(*tape, 1024);

// 0 filemarks
EXPECT_NO_THROW(Dispatch(tape, scsi_command::write_filemarks_16));

// 100 filemarks
controller->SetCdbByte(14, 100);
EXPECT_NO_THROW(Dispatch(tape, scsi_command::write_filemarks_16));
CheckPositions(tape, 400, 0);

// 100 filemarks
controller->SetCdbByte(14, 100);
Dispatch(tape, scsi_command::write_filemarks_16, sense_key::volume_overflow);
CheckPositions(tape, 512, 0);

tape->SetProtected(true);
Dispatch(tape, scsi_command::write_filemarks_16, sense_key::data_protect, asc::write_protected);
}

TEST(TapeTest, WriteFileMarks16_tar)
{
auto [controller, tape] = CreateTape();
CreateImageFile(*tape, 512, "tar");

EXPECT_NO_THROW(Dispatch(tape, scsi_command::write_filemarks_16));
}

TEST(TapeTest, Locate10_simh)
{
auto [controller, tape] = CreateTape();
Expand Down

0 comments on commit 69c59b5

Please sign in to comment.