Audio-SID
view release on metacpan or search on metacpan
$secondSIDModel = $self->getSIDModel(2);
$thirdSIDModel = $self->getSIDModel(3);
unless ($self->isRSID() ) {
$PlaySID = $self->isPlaySIDSpecific();
}
else {
$C64BASIC = $self->isC64BASIC();
}
$self->{SIDdata}{flags} = 0;
$self->setMUSPlayer($MUSPlayer);
$self->setClock($clock);
$self->setSIDModel($SIDModel);
if ($self->{SIDdata}{version} >= 3) {
if (defined($secondSIDModel)) {
$self->setSIDModel($secondSIDModel, 2);
}
}
if ($self->{SIDdata}{version} >= 4) {
if (defined($thirdSIDModel)) {
$self->setSIDModel($thirdSIDModel, 3);
}
}
unless ($self->isRSID() ) {
$self->setPlaySID($PlaySID);
}
else {
$self->setC64BASIC($C64BASIC);
}
}
if (($self->{SIDdata}{startPage} == 0) or ($self->{SIDdata}{startPage} == 0xFF)) {
$self->{SIDdata}{pageLength} = 0;
}
elsif ((($self->{SIDdata}{startPage} << 8) + ($self->{SIDdata}{pageLength} << 8) - 1) > 0xFFFF) {
$self->{SIDdata}{pageLength} = 0xFF - $self->{SIDdata}{startPage};
}
elsif ($self->{SIDdata}{pageLength} == 0) {
$self->{SIDdata}{pageLength} = 1;
}
if ($self->isRSID() ) {
# Reloc info must not overlap or encompass the ROM/IO and
# reserved memory areas.
# Is startPage within the ROM or reserved memory areas?
if ( (($self->{SIDdata}{startPage} >= 0xA0) and ($self->{SIDdata}{startPage} < 0xC0)) or
(($self->{SIDdata}{startPage} >= 0xD0) and ($self->{SIDdata}{startPage} < 0xFF)) or
(($self->{SIDdata}{startPage} > 0x00) and ($self->{SIDdata}{startPage} < 0x04)) ) {
$self->{SIDdata}{startPage} = 0xFF;
$self->{SIDdata}{pageLength} = 0x00;
}
# Is the end of the relocation range within the ROM or reserved memory areas?
if ( (( ($self->{SIDdata}{startPage} << 8) + ($self->{SIDdata}{pageLength} << 8) - 1 >= 0xA000) and ( ($self->{SIDdata}{startPage} << 8) + ($self->{SIDdata}{pageLength} << 8) - 1 < 0xC000)) or
(( ($self->{SIDdata}{startPage} << 8) + ($self->{SIDdata}{pageLength} << 8) - 1 >= 0xD000) and ( ($self->{SIDdata}{startPage} << 8) + ($self->{SIDdata}{pageLength} << 8) - 1 <= 0xFFFF)) or
(( ($self->{SIDdata}{startPage} << 8) + ($self->{SIDdata}{pageLength} << 8) - 1 > 0x0000) and ( ($self->{SIDdata}{startPage} << 8) + ($self->{SIDdata}{pageLength} << 8) - 1 < 0x0400)) ) {
$self->{SIDdata}{startPage} = 0xFF;
$self->{SIDdata}{pageLength} = 0x00;
}
# Does the relocation range encompass a ROM area?
if ( ($self->{SIDdata}{startPage} < 0xA0) and (($self->{SIDdata}{startPage} << 8) + ($self->{SIDdata}{pageLength} << 8) - 1 >= 0xC000) ) {
$self->{SIDdata}{startPage} = 0xFF;
$self->{SIDdata}{pageLength} = 0x00;
}
}
# Relocation range must not overlap or encompass the load range.
if ( (($self->{SIDdata}{startPage} << 8) >= $self->getRealLoadAddress()) and
(($self->{SIDdata}{startPage} << 8) <= ($self->getRealLoadAddress() + length($self->{SIDdata}{data}) - 3)
) ) {
$self->{SIDdata}{startPage} = 0xFF;
$self->{SIDdata}{pageLength} = 0x00;
}
if ( (($self->{SIDdata}{startPage} << 8) + ($self->{SIDdata}{pageLength} << 8) - 1 >= $self->getRealLoadAddress()) and
(($self->{SIDdata}{startPage} << 8) + ($self->{SIDdata}{pageLength} << 8) - 1 <= ($self->getRealLoadAddress() + length($self->{SIDdata}{data}) - 3))
) {
$self->{SIDdata}{startPage} = 0xFF;
$self->{SIDdata}{pageLength} = 0x00;
}
if ( (($self->{SIDdata}{startPage} << 8) < $self->getRealLoadAddress()) and
(($self->{SIDdata}{startPage} << 8) + ($self->{SIDdata}{pageLength} << 8) - 1 > ($self->getRealLoadAddress() + length($self->{SIDdata}{data}) - 3))
) {
$self->{SIDdata}{startPage} = 0xFF;
$self->{SIDdata}{pageLength} = 0x00;
}
$self->{SIDdata}{reserved} = 0;
if ($self->{SIDdata}{version} >= 3) {
# The secondSIDAddress field is valid only for v3+.
my $secondSIDAddress = $self->getSIDAddress(2);
if ($secondSIDAddress) {
# This function will also validate the value.
my $result = $self->setSIDAddress(2, $secondSIDAddress);
if (!$result) {
# Value validation failed, set SID address to 0.
$self->setSIDAddress(2, 0);
}
}
}
if ($self->{SIDdata}{version} >= 4) {
# The thirdSIDAddress field is valid only for v4+.
my $thirdSIDAddress = $self->getSIDAddress(3);
if ($thirdSIDAddress) {
# This function will also validate the value.
my $result = $self->setSIDAddress(3, $thirdSIDAddress);
if (!$result) {
# Value validation failed, set SID address to 0.
=item *
chopping the textual fields of I<title>, I<author> and I<released> to their
maximum length of 32 characters,
=item *
changing the characters of the textual fields of I<title>, I<author> and
I<released> to ISO 8859-1 ASCII bytes (i.e. NOT Unicode),
=item *
if the I<magicID> is 'RSID', changing the I<initAddress> to zero if it is
pointing to a ROM/IO area ($0000-$07E8, $A000-$BFFF or $D000-$FFFF), or if
the I<C64BASIC> flag is set to 1, and changing the I<initAddress> to zero if
it is outside the load range of the data and the I<magicID> is 'PSID',
=item *
changing the I<loadAddress> to 0 if it is non-zero (and also prepending the
I<data> with the non-zero I<loadAddress>)
=item *
making sure that I<loadAddress>, I<initAddress> and I<playAddress> are within
the $0000-$FFFF range (since the Commodore-64 had only 64KB addressable
memory), and setting them to 0 if they aren't,
=item *
making sure that I<startPage> and I<pageLength> are within the 0x00-0xFF
range, and setting them to 0 if they aren't,
=item *
making sure that I<songs> is within the range of [1,256], and changing it to
1 if it less than that or to 256 if it is more than that,
=item *
making sure that I<startSong> is within the range of [1,I<songs>], and changing
it to 1 if it is not,
=item *
setting only the relevant bits in I<speed>, regardless of how many bits were
set before, and setting the rest to 0,
=item *
setting only the recognized bits in I<flags>, namely 'MUSPlayer',
'psidSpecific', 'clock', 'sidModel', 'second sidModel' (version 3+ only), and
'third sidModel' (bits 0-9) (version 4+ only), and setting the rest to 0,
=item *
setting the I<pageLength> to 0 if I<startPage> is 0 or 0xFF,
=item *
setting the I<startPage> to 0xFF and the I<pageLength> to 0 if the relocation
range indicated by these two fields overlaps or encompasses the load range of
the C64 data,
=item *
setting the I<startPage> to 0xFF and the I<pageLength> to 0 if the I<magicID>
is 'RSID' and the relocation range indicated by these two fields overlaps or
encompasses the ROMs ($A000-$BFFF and $D000-$FFFF) or reserved memory
($0000-$03FF) areas,
=item *
setting the I<secondSIDAddress> and I<thirdSIDAddress> fields according to the
rules described for the I<setSIDAddress> function,
=item *
removing extra bytes that may have been between the SID header and I<data>
in the file (usually happens when I<dataOffset> is larger than the total size
of the SID header, i.e. larger than 0x007C),
=item *
setting the I<reserved> field to 0 if I<version> is less than 4, and setting it
to undef if I<version> is 4+,
=back
=back
=head1 BUGS
None is known to exist at this time. If you find any bugs in this module,
report them to the author (see L<"COPYRIGHT"> below).
=head1 TO DO LIST
More or less in order of perceived priority, from most urgent to least urgent.
=over 4
=item *
Add Stefano's SID player engine recognizer code.
=item *
Overload '=' so two objects can be assigned to each other?
=back
=head1 LICENSE
MIT License
Copyright 2017 LaLa (Imre Olajos)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
( run in 0.845 second using v1.01-cache-2.11-cpan-71847e10f99 )