NAME

D64::Disk::Layout::Base - A base class for designing physical layouts of various Commodore disk image formats

SYNOPSIS

  package D64::MyLayout;

  # Establish an ISA relationship with base class:
  use base qw(D64::Disk::Layout::Base);

  # Number of bytes per sector storage:
  our $bytes_per_sector = 256;

  # Number of sectors per track storage:
  our @sectors_per_track = ( 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, # tracks 1-17
                             19, 19, 19, 19, 19, 19, 19,                                         # tracks 18-24
                             18, 18, 18, 18, 18, 18,                                             # tracks 25-30
                             17, 17, 17, 17, 17, 17, 17, 17, 17, 17                              # tracks 31-40
                           );

  # Override default object constructor:
  sub new {
    my $class = shift;
    my $self = $class->SUPER::new(@_);
    if (defined $self) {
      bless $self, $class;
      return $self;
    }
    else {
      warn 'Failed to create new D64::MyLayout object';
      return undef;
    }
  }

  package main;

  # Read disk image data from file and create new derived class object instance:
  my $diskLayoutObj = D64::MyLayout->new('image.d64');

  # Get number of tracks available for use:
  my $num_tracks = $diskLayoutObj->num_tracks();
  # Get number of sectors per track information:
  my $num_sectors = $diskLayoutObj->num_sectors($track);

  # Read physical sector data from a disk image:
  my $data = $diskLayoutObj->sector_data($track, $sector);
  my @data = $diskLayoutObj->sector_data($track, $sector);

  # Write physical sector data into a disk image:
  $diskLayoutObj->sector_data($track, $sector, $data);
  $diskLayoutObj->sector_data($track, $sector, @data);

  # Read physical track data from a disk image:
  my $data = $diskLayoutObj->track_data($track);
  my @data = $diskLayoutObj->track_data($track);

  # Write physical track data into a disk image:
  $diskLayoutObj->track_data($track, $data);
  $diskLayoutObj->track_data($track, @data);

  # Save data changes to file:
  $diskLayoutObj->save();
  $diskLayoutObj->save_as('image.d64');

DESCRIPTION

This package provides a base class for designing physical layouts of various Commodore disk image formats, represented by data that can be allocated into tracks and sectors. The following two variables are required to be defined at a package-scope level of any derived class:

  our $bytes_per_sector = 256;

This scalar value defines number of bytes per sector storage.

  our @sectors_per_track = ( 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, # tracks 1-17
                             19, 19, 19, 19, 19, 19, 19,                                         # tracks 18-24
                             18, 18, 18, 18, 18, 18,                                             # tracks 25-30
                             17, 17, 17, 17, 17, 17, 17, 17, 17, 17                              # tracks 31-40
                           );

This list defines number of sectors per track storage.

Initialization of both these properties is always validated at compile-time within import method of the base class.

METHODS

new

Create empty unformatted disk image layout:

  my $diskLayoutObj = D64::Disk::Layout::Base->new();

Read disk image layout from existing file:

  my $diskLayoutObj = D64::Disk::Layout::Base->new('image.d64');

A valid D64::Disk::Layout::Base object is returned upon success, an undefined value otherwise.

You are most likely wanting to override this method in your derived class source code by calling it first to create an object and then reblessing a referenced object currently belonging to the base class:

  use base qw(D64::Disk::Layout::Base);

  sub new {
    my $class = shift;
    my $self = $class->SUPER::new(@_);
    if (defined $self) {
      bless $self, $class;
      return $self;
    }
    else {
      warn 'Failed to create new D64::MyLayout object';
      return undef;
    }
  }

Creating a new object may fail upon one of the following conditions:

  • File specified as an input parameter does not exist or cannot be read

  • File is too short, what causes inability to read complete sector data

sector_data

Read physical sector data from a disk image:

  my $data = $diskLayoutObj->sector_data($track, $sector);
  my @data = $diskLayoutObj->sector_data($track, $sector);

Can either be read into a scalar (in which case it is a bytes sequence) or into an array (method called in a list context returns a list of single bytes of data). Length of a scalar as well as size of an array depends on number of bytes per sector storage defined within derived class in $bytes_per_sector variable.

A valid sector data is returned upon successful read, an undefined value otherwise.

Write physical sector data into a disk image:

  $diskLayoutObj->sector_data($track, $sector, $data);
  $diskLayoutObj->sector_data($track, $sector, @data);

Same as above, data to write can be provided as a scalar (a bytes sequence of strictly defined length) as well as an array (list of single bytes of data of precisely specified size).

A valid sector data is returned upon successful write, an undefined value otherwise.

track_data

Read physical track data from a disk image:

  my $data = $diskLayoutObj->track_data($track);
  my @data = $diskLayoutObj->track_data($track);

Can either be read into a scalar (in which case it is a bytes sequence) or into an array (method called in a list context returns a list of single bytes of data). Length of a scalar as well as size of an array depend on number of bytes per sector storage defined within derived class in $bytes_per_sector attribute and number of sectors per track storage defined within derived class in @sectors_per_track property.

A valid track data is returned upon successful read, an undefined value otherwise.

Write physical track data into a disk image:

  $diskLayoutObj->track_data($track, $data);
  $diskLayoutObj->track_data($track, @data);

Same as above, data to write can be provided as a scalar (a bytes sequence of strictly defined length) as well as an array (list of single bytes of data of precisely specified size).

A valid track data is returned upon successful write, an undefined value otherwise.

num_tracks

Get number of tracks available:

  my $num_tracks = $diskLayoutObj->num_tracks();

num_sectors

Get number of sectors per track:

  my $num_sectors = $diskLayoutObj->num_sectors($track);

Number of sectors per specified track is returned upon success, an undefined value otherwise.

save

Save disk layout data to previously loaded image file:

  my $saveOK = $diskLayoutObj->save();

This method will not work when layout object is created as an empty unformatted disk image. Creating empty unformatted disk image layout forces usage of "save_as" method to save data by providing a filename to create new file. Disk layout object needs to be created by reading disk image layout from existing file to make this particular subroutine operative.

Returns true value upon successful write, and false otherwise.

save_as

Save disk layout data to file with specified name:

  my $saveOK = $diskLayoutObj->save_as('image.d64');

A behaviour implemented in this method prevents from overwriting an existing file unless it is the same file as the one that data has been previously read from (the same file that was used while creating this object instance).

Returns true value upon successful write, and false otherwise.

BUGS

There are no known bugs at the moment. Please report any bugs or feature requests.

EXPORT

None. No method is exported into the caller's namespace either by default or explicitly.

SEE ALSO

D64::Disk::Image

AUTHOR

Pawel Krol, <pawelkrol@cpan.org>.

VERSION

Version 0.03 (2021-01-12)

COPYRIGHT AND LICENSE

Copyright 2011-2021 by Pawel Krol <pawelkrol@cpan.org>.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.