Implemented basic residfp support
parent
540069c019
commit
08dc22009d
|
@ -142,6 +142,7 @@
|
||||||
835CBC8118DA7A520087A03E /* modplay.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 835CBC7618DA79F80087A03E /* modplay.bundle */; };
|
835CBC8118DA7A520087A03E /* modplay.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 835CBC7618DA79F80087A03E /* modplay.bundle */; };
|
||||||
8360EF6D17F92E56005208A4 /* HighlyComplete.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8360EF0517F92B24005208A4 /* HighlyComplete.bundle */; };
|
8360EF6D17F92E56005208A4 /* HighlyComplete.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8360EF0517F92B24005208A4 /* HighlyComplete.bundle */; };
|
||||||
836D28A818086386005B7299 /* MiniModeMenuTitleTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 836D28A718086386005B7299 /* MiniModeMenuTitleTransformer.m */; };
|
836D28A818086386005B7299 /* MiniModeMenuTitleTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 836D28A718086386005B7299 /* MiniModeMenuTitleTransformer.m */; };
|
||||||
|
836F5BF91A357A01002730CC /* sidplay.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8314D6411A354DFF00EEE8E6 /* sidplay.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
836F706218BDD1230095E648 /* vgmstream.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 836F6B2E18BDB80E0095E648 /* vgmstream.bundle */; };
|
836F706218BDD1230095E648 /* vgmstream.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 836F6B2E18BDB80E0095E648 /* vgmstream.bundle */; };
|
||||||
836FB5A718206F2500B3AD2D /* Hively.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 836FB5471820538800B3AD2D /* Hively.bundle */; };
|
836FB5A718206F2500B3AD2D /* Hively.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 836FB5471820538800B3AD2D /* Hively.bundle */; };
|
||||||
8375B36517FFEF130092A79F /* Opus.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8375B05717FFEA410092A79F /* Opus.bundle */; };
|
8375B36517FFEF130092A79F /* Opus.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8375B05717FFEA410092A79F /* Opus.bundle */; };
|
||||||
|
@ -423,6 +424,13 @@
|
||||||
remoteGlobalIDString = 99B989F40CC7E10400C256E9;
|
remoteGlobalIDString = 99B989F40CC7E10400C256E9;
|
||||||
remoteInfo = "APL Plugin";
|
remoteInfo = "APL Plugin";
|
||||||
};
|
};
|
||||||
|
8314D6401A354DFF00EEE8E6 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 8314D63B1A354DFE00EEE8E6 /* sidplay.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = 8314D6311A354DFE00EEE8E6;
|
||||||
|
remoteInfo = sidplay;
|
||||||
|
};
|
||||||
8359FF3017FEF35D0060F3ED /* PBXContainerItemProxy */ = {
|
8359FF3017FEF35D0060F3ED /* PBXContainerItemProxy */ = {
|
||||||
isa = PBXContainerItemProxy;
|
isa = PBXContainerItemProxy;
|
||||||
containerPortal = 8359FF2C17FEF35C0060F3ED /* ArchiveSource.xcodeproj */;
|
containerPortal = 8359FF2C17FEF35C0060F3ED /* ArchiveSource.xcodeproj */;
|
||||||
|
@ -444,6 +452,13 @@
|
||||||
remoteGlobalIDString = 8360EEE417F92AC8005208A4;
|
remoteGlobalIDString = 8360EEE417F92AC8005208A4;
|
||||||
remoteInfo = HighlyComplete;
|
remoteInfo = HighlyComplete;
|
||||||
};
|
};
|
||||||
|
836F5BED1A3579F5002730CC /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 8314D63B1A354DFE00EEE8E6 /* sidplay.xcodeproj */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 8314D6301A354DFE00EEE8E6;
|
||||||
|
remoteInfo = sidplay;
|
||||||
|
};
|
||||||
836F6B2D18BDB80E0095E648 /* PBXContainerItemProxy */ = {
|
836F6B2D18BDB80E0095E648 /* PBXContainerItemProxy */ = {
|
||||||
isa = PBXContainerItemProxy;
|
isa = PBXContainerItemProxy;
|
||||||
containerPortal = 836F6B2518BDB80D0095E648 /* vgmstream.xcodeproj */;
|
containerPortal = 836F6B2518BDB80D0095E648 /* vgmstream.xcodeproj */;
|
||||||
|
@ -651,6 +666,7 @@
|
||||||
dstPath = "";
|
dstPath = "";
|
||||||
dstSubfolderSpec = 13;
|
dstSubfolderSpec = 13;
|
||||||
files = (
|
files = (
|
||||||
|
836F5BF91A357A01002730CC /* sidplay.bundle in CopyFiles */,
|
||||||
839BD010196521E600947767 /* BASSMODS.bundle in CopyFiles */,
|
839BD010196521E600947767 /* BASSMODS.bundle in CopyFiles */,
|
||||||
835CBC8118DA7A520087A03E /* modplay.bundle in CopyFiles */,
|
835CBC8118DA7A520087A03E /* modplay.bundle in CopyFiles */,
|
||||||
836F706218BDD1230095E648 /* vgmstream.bundle in CopyFiles */,
|
836F706218BDD1230095E648 /* vgmstream.bundle in CopyFiles */,
|
||||||
|
@ -892,6 +908,7 @@
|
||||||
56DB084B0D6717DC00453B6A /* NSNumber+CogSort.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSNumber+CogSort.m"; path = "Spotlight/NSNumber+CogSort.m"; sourceTree = "<group>"; };
|
56DB084B0D6717DC00453B6A /* NSNumber+CogSort.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSNumber+CogSort.m"; path = "Spotlight/NSNumber+CogSort.m"; sourceTree = "<group>"; };
|
||||||
56DB08530D67185300453B6A /* NSArray+CogSort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSArray+CogSort.h"; path = "Spotlight/NSArray+CogSort.h"; sourceTree = "<group>"; };
|
56DB08530D67185300453B6A /* NSArray+CogSort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSArray+CogSort.h"; path = "Spotlight/NSArray+CogSort.h"; sourceTree = "<group>"; };
|
||||||
56DB08540D67185300453B6A /* NSArray+CogSort.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSArray+CogSort.m"; path = "Spotlight/NSArray+CogSort.m"; sourceTree = "<group>"; };
|
56DB08540D67185300453B6A /* NSArray+CogSort.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSArray+CogSort.m"; path = "Spotlight/NSArray+CogSort.m"; sourceTree = "<group>"; };
|
||||||
|
8314D63B1A354DFE00EEE8E6 /* sidplay.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = sidplay.xcodeproj; path = Plugins/sidplay/sidplay.xcodeproj; sourceTree = "<group>"; };
|
||||||
832C1252180BD1E2005507C1 /* Cog.help */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Cog.help; sourceTree = "<group>"; };
|
832C1252180BD1E2005507C1 /* Cog.help */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Cog.help; sourceTree = "<group>"; };
|
||||||
8355D6B4180612F300D05687 /* NSData+MD5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+MD5.h"; sourceTree = "<group>"; };
|
8355D6B4180612F300D05687 /* NSData+MD5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+MD5.h"; sourceTree = "<group>"; };
|
||||||
8355D6B5180612F300D05687 /* NSData+MD5.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+MD5.m"; sourceTree = "<group>"; };
|
8355D6B5180612F300D05687 /* NSData+MD5.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+MD5.m"; sourceTree = "<group>"; };
|
||||||
|
@ -1261,6 +1278,7 @@
|
||||||
836FB5421820538700B3AD2D /* Hively.xcodeproj */,
|
836FB5421820538700B3AD2D /* Hively.xcodeproj */,
|
||||||
836F6B2518BDB80D0095E648 /* vgmstream.xcodeproj */,
|
836F6B2518BDB80D0095E648 /* vgmstream.xcodeproj */,
|
||||||
839BCFE71965133E00947767 /* BASSMODS.xcodeproj */,
|
839BCFE71965133E00947767 /* BASSMODS.xcodeproj */,
|
||||||
|
8314D63B1A354DFE00EEE8E6 /* sidplay.xcodeproj */,
|
||||||
);
|
);
|
||||||
name = PlugIns;
|
name = PlugIns;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1575,6 +1593,14 @@
|
||||||
name = Categories;
|
name = Categories;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
8314D63C1A354DFE00EEE8E6 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
8314D6411A354DFF00EEE8E6 /* sidplay.bundle */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
8359FF2D17FEF35C0060F3ED /* Products */ = {
|
8359FF2D17FEF35C0060F3ED /* Products */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -1679,9 +1705,9 @@
|
||||||
children = (
|
children = (
|
||||||
83E6B759181612FD00D4576D /* Sparkle.framework */,
|
83E6B759181612FD00D4576D /* Sparkle.framework */,
|
||||||
83E6B75B181612FD00D4576D /* Sparkle Test App.app */,
|
83E6B75B181612FD00D4576D /* Sparkle Test App.app */,
|
||||||
83E6B75D181612FD00D4576D /* Sparkle Unit Tests.octest */,
|
83E6B75D181612FD00D4576D /* Sparkle Unit Tests.xctest */,
|
||||||
83E6B75F181612FD00D4576D /* BinaryDelta */,
|
83E6B75F181612FD00D4576D /* BinaryDelta */,
|
||||||
83E6B761181612FD00D4576D /* finish_installation.app */,
|
83E6B761181612FD00D4576D /* Autoupdate.app */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1818,6 +1844,7 @@
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
|
836F5BEE1A3579F5002730CC /* PBXTargetDependency */,
|
||||||
839BD012196521FD00947767 /* PBXTargetDependency */,
|
839BD012196521FD00947767 /* PBXTargetDependency */,
|
||||||
836FB5A618206F1500B3AD2D /* PBXTargetDependency */,
|
836FB5A618206F1500B3AD2D /* PBXTargetDependency */,
|
||||||
83A0F4E21816DBE800119DB4 /* PBXTargetDependency */,
|
83A0F4E21816DBE800119DB4 /* PBXTargetDependency */,
|
||||||
|
@ -1973,6 +2000,10 @@
|
||||||
ProductGroup = 17C808A80C3BD1BA005707C4 /* Products */;
|
ProductGroup = 17C808A80C3BD1BA005707C4 /* Products */;
|
||||||
ProjectRef = 17C808A70C3BD1BA005707C4 /* Shorten.xcodeproj */;
|
ProjectRef = 17C808A70C3BD1BA005707C4 /* Shorten.xcodeproj */;
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
ProductGroup = 8314D63C1A354DFE00EEE8E6 /* Products */;
|
||||||
|
ProjectRef = 8314D63B1A354DFE00EEE8E6 /* sidplay.xcodeproj */;
|
||||||
|
},
|
||||||
{
|
{
|
||||||
ProductGroup = 83E6B751181612FD00D4576D /* Products */;
|
ProductGroup = 83E6B751181612FD00D4576D /* Products */;
|
||||||
ProjectRef = 83E6B750181612FD00D4576D /* Sparkle.xcodeproj */;
|
ProjectRef = 83E6B750181612FD00D4576D /* Sparkle.xcodeproj */;
|
||||||
|
@ -2107,6 +2138,13 @@
|
||||||
remoteRef = 566D321A0D538550004466A5 /* PBXContainerItemProxy */;
|
remoteRef = 566D321A0D538550004466A5 /* PBXContainerItemProxy */;
|
||||||
sourceTree = BUILT_PRODUCTS_DIR;
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
};
|
};
|
||||||
|
8314D6411A354DFF00EEE8E6 /* sidplay.bundle */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = wrapper.cfbundle;
|
||||||
|
path = sidplay.bundle;
|
||||||
|
remoteRef = 8314D6401A354DFF00EEE8E6 /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
8359FF3117FEF35D0060F3ED /* ArchiveSource.bundle */ = {
|
8359FF3117FEF35D0060F3ED /* ArchiveSource.bundle */ = {
|
||||||
isa = PBXReferenceProxy;
|
isa = PBXReferenceProxy;
|
||||||
fileType = wrapper.cfbundle;
|
fileType = wrapper.cfbundle;
|
||||||
|
@ -2191,10 +2229,10 @@
|
||||||
remoteRef = 83E6B75A181612FD00D4576D /* PBXContainerItemProxy */;
|
remoteRef = 83E6B75A181612FD00D4576D /* PBXContainerItemProxy */;
|
||||||
sourceTree = BUILT_PRODUCTS_DIR;
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
};
|
};
|
||||||
83E6B75D181612FD00D4576D /* Sparkle Unit Tests.octest */ = {
|
83E6B75D181612FD00D4576D /* Sparkle Unit Tests.xctest */ = {
|
||||||
isa = PBXReferenceProxy;
|
isa = PBXReferenceProxy;
|
||||||
fileType = wrapper.cfbundle;
|
fileType = wrapper.cfbundle;
|
||||||
path = "Sparkle Unit Tests.octest";
|
path = "Sparkle Unit Tests.xctest";
|
||||||
remoteRef = 83E6B75C181612FD00D4576D /* PBXContainerItemProxy */;
|
remoteRef = 83E6B75C181612FD00D4576D /* PBXContainerItemProxy */;
|
||||||
sourceTree = BUILT_PRODUCTS_DIR;
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
};
|
};
|
||||||
|
@ -2205,10 +2243,10 @@
|
||||||
remoteRef = 83E6B75E181612FD00D4576D /* PBXContainerItemProxy */;
|
remoteRef = 83E6B75E181612FD00D4576D /* PBXContainerItemProxy */;
|
||||||
sourceTree = BUILT_PRODUCTS_DIR;
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
};
|
};
|
||||||
83E6B761181612FD00D4576D /* finish_installation.app */ = {
|
83E6B761181612FD00D4576D /* Autoupdate.app */ = {
|
||||||
isa = PBXReferenceProxy;
|
isa = PBXReferenceProxy;
|
||||||
fileType = wrapper.application;
|
fileType = wrapper.application;
|
||||||
path = finish_installation.app;
|
path = Autoupdate.app;
|
||||||
remoteRef = 83E6B760181612FD00D4576D /* PBXContainerItemProxy */;
|
remoteRef = 83E6B760181612FD00D4576D /* PBXContainerItemProxy */;
|
||||||
sourceTree = BUILT_PRODUCTS_DIR;
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
};
|
};
|
||||||
|
@ -2510,6 +2548,11 @@
|
||||||
name = General;
|
name = General;
|
||||||
targetProxy = 17F5623A0C3BD9280019975C /* PBXContainerItemProxy */;
|
targetProxy = 17F5623A0C3BD9280019975C /* PBXContainerItemProxy */;
|
||||||
};
|
};
|
||||||
|
836F5BEE1A3579F5002730CC /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
name = sidplay;
|
||||||
|
targetProxy = 836F5BED1A3579F5002730CC /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
836FB5A618206F1500B3AD2D /* PBXTargetDependency */ = {
|
836FB5A618206F1500B3AD2D /* PBXTargetDependency */ = {
|
||||||
isa = PBXTargetDependency;
|
isa = PBXTargetDependency;
|
||||||
name = Hively;
|
name = Hively;
|
||||||
|
|
|
@ -8,14 +8,23 @@
|
||||||
<string>811E8515-6C50-44FF-ACDB-088BB9917E26</string>
|
<string>811E8515-6C50-44FF-ACDB-088BB9917E26</string>
|
||||||
<key>IDESourceControlProjectOriginsDictionary</key>
|
<key>IDESourceControlProjectOriginsDictionary</key>
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>75748be7-0387-4326-94c7-f41ce0883d2c++505</key>
|
||||||
|
<string>svn://svn.code.sf.net/p/sidplay-residfp/code/trunk</string>
|
||||||
<key>EF1CF5E1F342919DE309B5C9DAEDDCF1D12D0402</key>
|
<key>EF1CF5E1F342919DE309B5C9DAEDDCF1D12D0402</key>
|
||||||
<string>https://github.com/andymatuschak/Sparkle.git</string>
|
<string>https://github.com/andymatuschak/Sparkle.git</string>
|
||||||
</dict>
|
</dict>
|
||||||
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
|
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>75748be7-0387-4326-94c7-f41ce0883d2c++505</key>
|
||||||
|
<string>libsidplay/sidplay-residfp-code/</string>
|
||||||
<key>EF1CF5E1F342919DE309B5C9DAEDDCF1D12D0402</key>
|
<key>EF1CF5E1F342919DE309B5C9DAEDDCF1D12D0402</key>
|
||||||
<string>Sparkle/</string>
|
<string>Sparkle/</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
<key>IDESourceControlProjectRepositoryRootDictionary</key>
|
||||||
|
<dict>
|
||||||
|
<key>75748be7-0387-4326-94c7-f41ce0883d2c++505</key>
|
||||||
|
<string>svn://svn.code.sf.net/p/sidplay-residfp/code</string>
|
||||||
|
</dict>
|
||||||
<key>IDESourceControlProjectURL</key>
|
<key>IDESourceControlProjectURL</key>
|
||||||
<string>https://github.com/andymatuschak/Sparkle.git</string>
|
<string>https://github.com/andymatuschak/Sparkle.git</string>
|
||||||
<key>IDESourceControlProjectVersion</key>
|
<key>IDESourceControlProjectVersion</key>
|
||||||
|
@ -24,6 +33,14 @@
|
||||||
<string>EF1CF5E1F342919DE309B5C9DAEDDCF1D12D0402</string>
|
<string>EF1CF5E1F342919DE309B5C9DAEDDCF1D12D0402</string>
|
||||||
<key>IDESourceControlProjectWCConfigurations</key>
|
<key>IDESourceControlProjectWCConfigurations</key>
|
||||||
<array>
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
|
||||||
|
<string>public.vcs.subversion</string>
|
||||||
|
<key>IDESourceControlWCCIdentifierKey</key>
|
||||||
|
<string>75748be7-0387-4326-94c7-f41ce0883d2c++505</string>
|
||||||
|
<key>IDESourceControlWCCName</key>
|
||||||
|
<string>sidplay-residfp-code</string>
|
||||||
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
|
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
|
||||||
<string>public.vcs.git</string>
|
<string>public.vcs.git</string>
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>en</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>org.cogx.$(PRODUCT_NAME:rfc1034identifier)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>$(PRODUCT_NAME)</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>FMWK</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||||
|
<key>NSHumanReadableCopyright</key>
|
||||||
|
<string>Copyright © 2014 Christopher Snowhill. All rights reserved.</string>
|
||||||
|
<key>NSPrincipalClass</key>
|
||||||
|
<string></string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -0,0 +1 @@
|
||||||
|
12
|
|
@ -0,0 +1 @@
|
||||||
|
12
|
|
@ -0,0 +1,157 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2011-2014 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
* Copyright 2007-2010 Antti Lankila
|
||||||
|
* Copyright 2001-2002 by Jarno Paananen
|
||||||
|
* Copyright 2000-2002 Simon White
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HARDSID_EMU_H
|
||||||
|
#define HARDSID_EMU_H
|
||||||
|
|
||||||
|
#include "sidplayfp/event.h"
|
||||||
|
#include "sidemu.h"
|
||||||
|
#include "EventScheduler.h"
|
||||||
|
#include "sidplayfp/siddefs.h"
|
||||||
|
|
||||||
|
#include "sidcxx11.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class sidbuilder;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#define HSID_VERSION_MIN (WORD) 0x0200
|
||||||
|
#define HSID_VERSION_204 (WORD) 0x0204
|
||||||
|
#define HSID_VERSION_207 (WORD) 0x0207
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// Version 2 Interface
|
||||||
|
typedef void (CALLBACK* HsidDLL2_Delay_t) (BYTE deviceID, WORD cycles);
|
||||||
|
typedef BYTE (CALLBACK* HsidDLL2_Devices_t) ();
|
||||||
|
typedef void (CALLBACK* HsidDLL2_Filter_t) (BYTE deviceID, BOOL filter);
|
||||||
|
typedef void (CALLBACK* HsidDLL2_Flush_t) (BYTE deviceID);
|
||||||
|
typedef void (CALLBACK* HsidDLL2_Mute_t) (BYTE deviceID, BYTE channel, BOOL mute);
|
||||||
|
typedef void (CALLBACK* HsidDLL2_MuteAll_t) (BYTE deviceID, BOOL mute);
|
||||||
|
typedef void (CALLBACK* HsidDLL2_Reset_t) (BYTE deviceID);
|
||||||
|
typedef BYTE (CALLBACK* HsidDLL2_Read_t) (BYTE deviceID, WORD cycles, BYTE SID_reg);
|
||||||
|
typedef void (CALLBACK* HsidDLL2_Sync_t) (BYTE deviceID);
|
||||||
|
typedef void (CALLBACK* HsidDLL2_Write_t) (BYTE deviceID, WORD cycles, BYTE SID_reg, BYTE data);
|
||||||
|
typedef WORD (CALLBACK* HsidDLL2_Version_t) ();
|
||||||
|
|
||||||
|
// Version 2.04 Extensions
|
||||||
|
typedef BOOL (CALLBACK* HsidDLL2_Lock_t) (BYTE deviceID);
|
||||||
|
typedef void (CALLBACK* HsidDLL2_Unlock_t) (BYTE deviceID);
|
||||||
|
typedef void (CALLBACK* HsidDLL2_Reset2_t) (BYTE deviceID, BYTE volume);
|
||||||
|
|
||||||
|
// Version 2.07 Extensions
|
||||||
|
typedef void (CALLBACK* HsidDLL2_Mute2_t) (BYTE deviceID, BYTE channel, BOOL mute, BOOL manual);
|
||||||
|
|
||||||
|
struct HsidDLL2
|
||||||
|
{
|
||||||
|
HINSTANCE Instance;
|
||||||
|
HsidDLL2_Delay_t Delay;
|
||||||
|
HsidDLL2_Devices_t Devices;
|
||||||
|
HsidDLL2_Filter_t Filter;
|
||||||
|
HsidDLL2_Flush_t Flush;
|
||||||
|
HsidDLL2_Lock_t Lock;
|
||||||
|
HsidDLL2_Unlock_t Unlock;
|
||||||
|
HsidDLL2_Mute_t Mute;
|
||||||
|
HsidDLL2_Mute2_t Mute2;
|
||||||
|
HsidDLL2_MuteAll_t MuteAll;
|
||||||
|
HsidDLL2_Reset_t Reset;
|
||||||
|
HsidDLL2_Reset2_t Reset2;
|
||||||
|
HsidDLL2_Read_t Read;
|
||||||
|
HsidDLL2_Sync_t Sync;
|
||||||
|
HsidDLL2_Write_t Write;
|
||||||
|
WORD Version;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
#define HARDSID_VOICES 3
|
||||||
|
// Approx 60ms
|
||||||
|
#define HARDSID_DELAY_CYCLES 60000
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* HardSID SID Specialisation
|
||||||
|
***************************************************************************/
|
||||||
|
class HardSID : public sidemu, private Event
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
friend class HardSIDBuilder;
|
||||||
|
|
||||||
|
// HardSID specific data
|
||||||
|
#ifndef _WIN32
|
||||||
|
static bool m_sidFree[16];
|
||||||
|
int m_handle;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const unsigned int voices;
|
||||||
|
static unsigned int sid;
|
||||||
|
|
||||||
|
// Must stay in this order
|
||||||
|
bool muted[HARDSID_VOICES];
|
||||||
|
unsigned int m_instance;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const char* getCredits();
|
||||||
|
|
||||||
|
public:
|
||||||
|
HardSID(sidbuilder *builder);
|
||||||
|
~HardSID();
|
||||||
|
|
||||||
|
bool getStatus() const { return m_status; }
|
||||||
|
|
||||||
|
// Standard component functions
|
||||||
|
void reset() override { sidemu::reset(); }
|
||||||
|
|
||||||
|
uint8_t read(uint_least8_t addr) override;
|
||||||
|
void write(uint_least8_t addr, uint8_t data) override;
|
||||||
|
|
||||||
|
// c64sid functions
|
||||||
|
void reset(uint8_t volume) override;
|
||||||
|
|
||||||
|
// Standard SID functions
|
||||||
|
void clock() override;
|
||||||
|
|
||||||
|
void model(SidConfig::sid_model_t) override {}
|
||||||
|
|
||||||
|
void voice(unsigned int num, bool mute) override;
|
||||||
|
|
||||||
|
// HardSID specific
|
||||||
|
void flush();
|
||||||
|
void filter(bool enable);
|
||||||
|
|
||||||
|
// Must lock the SID before using the standard functions.
|
||||||
|
bool lock(EventContext *env) override;
|
||||||
|
void unlock() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Fixed interval timer delay to prevent sidplay2
|
||||||
|
// shoot to 100% CPU usage when song nolonger
|
||||||
|
// writes to SID.
|
||||||
|
void event() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HARDSID_EMU_H
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* This file is part of sidplayfp, a console SID player.
|
||||||
|
*
|
||||||
|
* Copyright 2013-2014 Leandro Nini
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# include <windows.h>
|
||||||
|
# include <shlobj.h>
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
# define _tgetenv _wgetenv
|
||||||
|
#else
|
||||||
|
# define _tgetenv getenv
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SID_STRING utils::getPath()
|
||||||
|
{
|
||||||
|
SID_STRING returnPath;
|
||||||
|
|
||||||
|
TCHAR szPath[MAX_PATH];
|
||||||
|
|
||||||
|
if (SHGetFolderPath(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, NULL, 0, szPath)!=S_OK)
|
||||||
|
{
|
||||||
|
TCHAR *path = _tgetenv(TEXT("USERPROFILE"));
|
||||||
|
if (!path)
|
||||||
|
throw error();
|
||||||
|
returnPath.append(path).append(TEXT("\\Application Data"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
returnPath.append(szPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
SID_STRING utils::getDataPath() { return getPath(); }
|
||||||
|
|
||||||
|
SID_STRING utils::getConfigPath() { return getPath(); }
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
SID_STRING utils::getPath(const char* id, const char* def)
|
||||||
|
{
|
||||||
|
SID_STRING returnPath;
|
||||||
|
|
||||||
|
char *path = getenv(id);
|
||||||
|
if (!path)
|
||||||
|
{
|
||||||
|
path = getenv("HOME");
|
||||||
|
if (!path)
|
||||||
|
throw error();
|
||||||
|
returnPath.append(path).append(def);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
returnPath.append(path);
|
||||||
|
|
||||||
|
return returnPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
SID_STRING utils::getDataPath() { return getPath("XDG_DATA_HOME", "/.local/share"); }
|
||||||
|
|
||||||
|
SID_STRING utils::getConfigPath() { return getPath("XDG_CONFIG_HOME", "/.config"); }
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2011-2013 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
* Copyright 2007-2010 Antti Lankila
|
||||||
|
* Copyright 2004,2010 Dag Lem <resid@nimrod.no>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Dac.h"
|
||||||
|
|
||||||
|
namespace reSIDfp
|
||||||
|
{
|
||||||
|
|
||||||
|
void Dac::kinkedDac(double* dac, int dacLength, double _2R_div_R, bool term)
|
||||||
|
{
|
||||||
|
const double R_INFINITY = 1e6;
|
||||||
|
|
||||||
|
// Calculate voltage contribution by each individual bit in the R-2R ladder.
|
||||||
|
for (int set_bit = 0; set_bit < dacLength; set_bit++)
|
||||||
|
{
|
||||||
|
double Vn = 1.; // Normalized bit voltage.
|
||||||
|
double R = 1.; // Normalized R
|
||||||
|
const double _2R = _2R_div_R * R; // 2R
|
||||||
|
double Rn = term ? // Rn = 2R for correct termination,
|
||||||
|
_2R : R_INFINITY; // INFINITY for missing termination.
|
||||||
|
|
||||||
|
int bit;
|
||||||
|
|
||||||
|
// Calculate DAC "tail" resistance by repeated parallel substitution.
|
||||||
|
for (bit = 0; bit < set_bit; bit++)
|
||||||
|
{
|
||||||
|
Rn = (Rn == R_INFINITY) ?
|
||||||
|
R + _2R :
|
||||||
|
R + _2R * Rn / (_2R + Rn); // R + 2R || Rn
|
||||||
|
}
|
||||||
|
|
||||||
|
// Source transformation for bit voltage.
|
||||||
|
if (Rn == R_INFINITY)
|
||||||
|
{
|
||||||
|
Rn = _2R;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Rn = _2R * Rn / (_2R + Rn); // 2R || Rn
|
||||||
|
Vn = Vn * Rn / _2R;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate DAC output voltage by repeated source transformation from
|
||||||
|
// the "tail".
|
||||||
|
|
||||||
|
for (++bit; bit < dacLength; bit++)
|
||||||
|
{
|
||||||
|
Rn += R;
|
||||||
|
const double I = Vn / Rn;
|
||||||
|
Rn = _2R * Rn / (_2R + Rn); // 2R || Rn
|
||||||
|
Vn = Rn * I;
|
||||||
|
}
|
||||||
|
|
||||||
|
dac[set_bit] = Vn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalize to integerish behavior
|
||||||
|
double Vsum = 0.;
|
||||||
|
|
||||||
|
for (int i = 0; i < dacLength; i ++)
|
||||||
|
{
|
||||||
|
Vsum += dac[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
Vsum /= 1 << dacLength;
|
||||||
|
|
||||||
|
for (int i = 0; i < dacLength; i ++)
|
||||||
|
{
|
||||||
|
dac[i] /= Vsum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace reSIDfp
|
Binary file not shown.
|
@ -0,0 +1,56 @@
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// This file is part of reSID, a MOS6581 SID emulator engine.
|
||||||
|
// Copyright (C) 1999 Dag Lem <resid@nimrod.no>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef SIDDEFS_FP_H
|
||||||
|
#define SIDDEFS_FP_H
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
# define M_PI 3.14159265358979323846
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Branch prediction macros, lifted off the Linux kernel.
|
||||||
|
#if RESID_BRANCH_HINTS && HAVE_BUILTIN_EXPECT
|
||||||
|
# define likely(x) __builtin_expect(!!(x), 1)
|
||||||
|
# define unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
|
#else
|
||||||
|
# define likely(x) (x)
|
||||||
|
# define unlikely(x) (x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace reSIDfp {
|
||||||
|
|
||||||
|
typedef enum { MOS6581=1, MOS8580 } ChipModel;
|
||||||
|
|
||||||
|
typedef enum { DECIMATE=1, RESAMPLE } SamplingMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#ifndef __VERSION_CC__
|
||||||
|
extern const char* residfp_version_string;
|
||||||
|
#else
|
||||||
|
const char* residfp_version_string = "@PACKAGE_VERSION@";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inlining on/off.
|
||||||
|
#define RESID_INLINING @RESID_INLINING@
|
||||||
|
#define RESID_INLINE @RESID_INLINE@
|
||||||
|
|
||||||
|
#endif // SIDDEFS_FP_H
|
|
@ -0,0 +1,256 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2011-2013 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
* Copyright 2007-2010 Antti Lankila
|
||||||
|
* Copyright 2004 Dag Lem <resid@nimrod.no>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SincResampler.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "siddefs-fp.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_MMINTRIN_H
|
||||||
|
# include <mmintrin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace reSIDfp
|
||||||
|
{
|
||||||
|
|
||||||
|
typedef std::map<std::string, matrix_t> fir_cache_t;
|
||||||
|
|
||||||
|
/// Cache for the expensive FIR table computation results.
|
||||||
|
fir_cache_t FIR_CACHE;
|
||||||
|
|
||||||
|
/// Maximum error acceptable in I0 is 1e-6, or ~96 dB.
|
||||||
|
const double I0E = 1e-6;
|
||||||
|
|
||||||
|
const int BITS = 16;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* I0() computes the 0th order modified Bessel function of the first kind.
|
||||||
|
* This function is originally from resample-1.5/filterkit.c by J. O. Smith.
|
||||||
|
* It is used to build the Kaiser window for resampling.
|
||||||
|
*
|
||||||
|
* @param x evaluate I0 at x
|
||||||
|
* @return value of I0 at x.
|
||||||
|
*/
|
||||||
|
double I0(double x)
|
||||||
|
{
|
||||||
|
double sum = 1., u = 1., n = 1.;
|
||||||
|
const double halfx = x / 2.;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
const double temp = halfx / n;
|
||||||
|
u *= temp * temp;
|
||||||
|
sum += u;
|
||||||
|
n += 1.;
|
||||||
|
}
|
||||||
|
while (u >= I0E * sum);
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate convolution with sample and sinc.
|
||||||
|
*
|
||||||
|
* @param a sample buffer input
|
||||||
|
* @param b sinc
|
||||||
|
* @param bLength length of the sinc buffer
|
||||||
|
* @return convolved result
|
||||||
|
*/
|
||||||
|
int convolve(const short* a, const short* b, int bLength)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_MMINTRIN_H
|
||||||
|
__m64 acc = _mm_setzero_si64();
|
||||||
|
|
||||||
|
const int n = bLength / 4;
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
const __m64 tmp = _mm_madd_pi16(*(__m64*)a, *(__m64*)b);
|
||||||
|
acc = _mm_add_pi16(acc, tmp);
|
||||||
|
a += 4;
|
||||||
|
b += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
int out = _mm_cvtsi64_si32(acc) + _mm_cvtsi64_si32(_mm_srli_si64(acc, 32));
|
||||||
|
_mm_empty();
|
||||||
|
|
||||||
|
bLength &= 3;
|
||||||
|
#else
|
||||||
|
int out = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (int i = 0; i < bLength; i++)
|
||||||
|
{
|
||||||
|
out += *a++ * *b++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (out + (1 << 14)) >> 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SincResampler::fir(int subcycle)
|
||||||
|
{
|
||||||
|
// find the first of the nearest fir tables close to the phase
|
||||||
|
int firTableFirst = (subcycle * firRES >> 10);
|
||||||
|
const int firTableOffset = (subcycle * firRES) & 0x3ff;
|
||||||
|
|
||||||
|
// find firN most recent samples, plus one extra in case the FIR wraps.
|
||||||
|
int sampleStart = sampleIndex - firN + RINGSIZE - 1;
|
||||||
|
|
||||||
|
const int v1 = convolve(sample + sampleStart, (*firTable)[firTableFirst], firN);
|
||||||
|
|
||||||
|
// Use next FIR table, wrap around to first FIR table using
|
||||||
|
// previous sample.
|
||||||
|
if (unlikely(++firTableFirst == firRES))
|
||||||
|
{
|
||||||
|
firTableFirst = 0;
|
||||||
|
++sampleStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int v2 = convolve(sample + sampleStart, (*firTable)[firTableFirst], firN);
|
||||||
|
|
||||||
|
// Linear interpolation between the sinc tables yields good
|
||||||
|
// approximation for the exact value.
|
||||||
|
return v1 + (firTableOffset * (v2 - v1) >> 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
SincResampler::SincResampler(double clockFrequency, double samplingFrequency, double highestAccurateFrequency) :
|
||||||
|
sampleIndex(0),
|
||||||
|
cyclesPerSample(static_cast<int>(clockFrequency / samplingFrequency * 1024.)),
|
||||||
|
sampleOffset(0),
|
||||||
|
outputValue(0)
|
||||||
|
{
|
||||||
|
// 16 bits -> -96dB stopband attenuation.
|
||||||
|
const double A = -20. * log10(1.0 / (1 << BITS));
|
||||||
|
// A fraction of the bandwidth is allocated to the transition band, which we double
|
||||||
|
// because we design the filter to transition halfway at nyquist.
|
||||||
|
const double dw = (1. - 2.*highestAccurateFrequency / samplingFrequency) * M_PI * 2.;
|
||||||
|
|
||||||
|
// For calculation of beta and N see the reference for the kaiserord
|
||||||
|
// function in the MATLAB Signal Processing Toolbox:
|
||||||
|
// http://www.mathworks.com/access/helpdesk/help/toolbox/signal/kaiserord.html
|
||||||
|
const double beta = 0.1102 * (A - 8.7);
|
||||||
|
const double I0beta = I0(beta);
|
||||||
|
const double cyclesPerSampleD = clockFrequency / samplingFrequency;
|
||||||
|
|
||||||
|
{
|
||||||
|
// The filter order will maximally be 124 with the current constraints.
|
||||||
|
// N >= (96.33 - 7.95)/(2 * pi * 2.285 * (maxfreq - passbandfreq) >= 123
|
||||||
|
// The filter order is equal to the number of zero crossings, i.e.
|
||||||
|
// it should be an even number (sinc is symmetric about x = 0).
|
||||||
|
int N = static_cast<int>((A - 7.95) / (2.285 * dw) + 0.5);
|
||||||
|
N += N & 1;
|
||||||
|
|
||||||
|
// The filter length is equal to the filter order + 1.
|
||||||
|
// The filter length must be an odd number (sinc is symmetric about
|
||||||
|
// x = 0).
|
||||||
|
firN = static_cast<int>(N * cyclesPerSampleD) + 1;
|
||||||
|
firN |= 1;
|
||||||
|
|
||||||
|
// Check whether the sample ring buffer would overflow.
|
||||||
|
assert(firN < RINGSIZE);
|
||||||
|
|
||||||
|
// Error is bounded by err < 1.234 / L^2, so L = sqrt(1.234 / (2^-16)) = sqrt(1.234 * 2^16).
|
||||||
|
firRES = static_cast<int>(ceil(sqrt(1.234 * (1 << BITS)) / cyclesPerSampleD));
|
||||||
|
|
||||||
|
// firN*firRES represent the total resolution of the sinc sampling. JOS
|
||||||
|
// recommends a length of 2^BITS, but we don't quite use that good a filter.
|
||||||
|
// The filter test program indicates that the filter performs well, though. */
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostringstream o;
|
||||||
|
o << firN << "," << firRES << "," << cyclesPerSampleD;
|
||||||
|
const std::string firKey = o.str();
|
||||||
|
fir_cache_t::iterator lb = FIR_CACHE.lower_bound(firKey);
|
||||||
|
|
||||||
|
// The FIR computation is expensive and we set sampling parameters often, but
|
||||||
|
// from a very small set of choices. Thus, caching is used to speed initialization.
|
||||||
|
if (lb != FIR_CACHE.end() && !(FIR_CACHE.key_comp()(firKey, lb->first)))
|
||||||
|
{
|
||||||
|
firTable = &(lb->second);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Allocate memory for FIR tables.
|
||||||
|
matrix_t tempTable(firRES, firN);
|
||||||
|
firTable = &(FIR_CACHE.insert(lb, fir_cache_t::value_type(firKey, tempTable))->second);
|
||||||
|
|
||||||
|
// The cutoff frequency is midway through the transition band, in effect the same as nyquist.
|
||||||
|
const double wc = M_PI;
|
||||||
|
|
||||||
|
// Calculate the sinc tables.
|
||||||
|
const double scale = 32768.0 * wc / cyclesPerSampleD / M_PI;
|
||||||
|
|
||||||
|
for (int i = 0; i < firRES; i++)
|
||||||
|
{
|
||||||
|
const double jPhase = (double) i / firRES + firN / 2;
|
||||||
|
|
||||||
|
for (int j = 0; j < firN; j++)
|
||||||
|
{
|
||||||
|
const double x = j - jPhase;
|
||||||
|
|
||||||
|
const double xt = x / (firN / 2);
|
||||||
|
const double kaiserXt = fabs(xt) < 1. ? I0(beta * sqrt(1. - xt * xt)) / I0beta : 0.;
|
||||||
|
|
||||||
|
const double wt = wc * x / cyclesPerSampleD;
|
||||||
|
const double sincWt = fabs(wt) >= 1e-8 ? sin(wt) / wt : 1.;
|
||||||
|
|
||||||
|
(*firTable)[i][j] = static_cast<short>(scale * sincWt * kaiserXt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SincResampler::input(int input)
|
||||||
|
{
|
||||||
|
bool ready = false;
|
||||||
|
|
||||||
|
sample[sampleIndex] = sample[sampleIndex + RINGSIZE] = input;
|
||||||
|
sampleIndex = (sampleIndex + 1) & (RINGSIZE - 1);
|
||||||
|
|
||||||
|
if (sampleOffset < 1024)
|
||||||
|
{
|
||||||
|
outputValue = fir(sampleOffset);
|
||||||
|
ready = true;
|
||||||
|
sampleOffset += cyclesPerSample;
|
||||||
|
}
|
||||||
|
|
||||||
|
sampleOffset -= 1024;
|
||||||
|
|
||||||
|
return ready;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SincResampler::reset()
|
||||||
|
{
|
||||||
|
memset(sample, 0, RINGSIZE * 2 * sizeof(sample[0]));
|
||||||
|
sampleOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace reSIDfp
|
|
@ -0,0 +1,724 @@
|
||||||
|
=encoding utf8
|
||||||
|
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
stilview - command-line program to help you retrieve the entries stored
|
||||||
|
in STIL.
|
||||||
|
|
||||||
|
|
||||||
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
B<stilview> [-b] [-d] [-e entry] [-f field] [-i] [-l HVSC base dir] [-m]
|
||||||
|
[-o] [-s] [-t tune number]
|
||||||
|
|
||||||
|
B<stilview> {[-h] | [-v]}
|
||||||
|
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
B<STILView> is a command-line driven program to help you retrieve the
|
||||||
|
entries stored in STIL fast and accurately. STILView uses the STIL C++
|
||||||
|
class heavily to do this, and in fact, the primary purpose of this
|
||||||
|
command-line program is to test that class (which is, BTW, used in many
|
||||||
|
GUI-based SID players, most notably in SIDPlay for Windows and XSIDPLAY
|
||||||
|
for Unix systems). However, it is user-friendly enough to be used by
|
||||||
|
non-programmers, too.
|
||||||
|
|
||||||
|
|
||||||
|
=head1 GLOSSARY
|
||||||
|
|
||||||
|
Some terms and STIL-related lingo in alphabetical order:
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
=item B<BUG ENTRY>
|
||||||
|
|
||||||
|
There exists a special file in HVSC (F</DOCUMENTS/BUGlist.txt>) that
|
||||||
|
lists all known bugs in SID tunes in HVSC. See the top of that file
|
||||||
|
for details about what's in it exactly. A BUG entry is like a
|
||||||
|
STIL entry, but it is contained in this BUGlist.txt file.
|
||||||
|
|
||||||
|
=item B<FIELD>
|
||||||
|
|
||||||
|
The smallest piece of information in a STIL entry. Currently
|
||||||
|
valid field names are NAME, TITLE, ARTIST and COMMENT.
|
||||||
|
|
||||||
|
=item B<FILE-GLOBAL COMMENT>
|
||||||
|
|
||||||
|
A special COMMENT field in a STIL entry for a
|
||||||
|
multi-tune SID file that refers to the whole SID, not just one tune in
|
||||||
|
it. These usually contain general information about the SID file
|
||||||
|
itself.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
/Hubbard_Rob/Gerry_the_Germ.sid
|
||||||
|
COMMENT: In Rob's own demo of this music, the tunes are named after the levels
|
||||||
|
in the original game.
|
||||||
|
(#1)
|
||||||
|
TITLE: Lungs
|
||||||
|
(#2)
|
||||||
|
TITLE: Kidney
|
||||||
|
(#7)
|
||||||
|
TITLE: End
|
||||||
|
|
||||||
|
=item B<HVSC>
|
||||||
|
|
||||||
|
High Voltage SID Collection. If you don't know what this is, you
|
||||||
|
downloaded the wrong program. :)
|
||||||
|
|
||||||
|
=item B<HVSC-RELATIVE PATHNAME>
|
||||||
|
|
||||||
|
The pathname plus filename of a SID file that can be found in your
|
||||||
|
HVSC, relative to the base directory of HVSC. It is always in
|
||||||
|
UNIX-style format, eg.: /Hubbard_Rob/Commando.sid refers to
|
||||||
|
Rob Hubbard's Commando.sid file within HVSC (which may actually be
|
||||||
|
found as C:\Music\HVSC\Hubbard_Rob\Commando.sid on your Windows PC).
|
||||||
|
|
||||||
|
=item B<MULTI-TUNE ENTRY>
|
||||||
|
|
||||||
|
A STIL entry that is referring to a SID file that has many tunes in it.
|
||||||
|
Each tune might have its own STIL block, which are separated by a
|
||||||
|
so-called tune designation in the form of "(#x)", where x = the
|
||||||
|
tune number. Consult the STIL.FAQ in HVSC for a detailed description.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
/Hubbard_Rob/Gerry_the_Germ.sid
|
||||||
|
COMMENT: In Rob's own demo of this music, the tunes are named after the levels
|
||||||
|
in the original game.
|
||||||
|
(#1)
|
||||||
|
TITLE: Lungs
|
||||||
|
(#2)
|
||||||
|
TITLE: Kidney
|
||||||
|
(#7)
|
||||||
|
TITLE: End
|
||||||
|
|
||||||
|
=item B<SECTION>
|
||||||
|
|
||||||
|
A part of STIL that belongs to one composer (ie. every STIL entry
|
||||||
|
referring to SID files that are in one subdirectory in HVSC).
|
||||||
|
Sections in STIL are always separated by a line in the form of: "###
|
||||||
|
Composer's name ########".
|
||||||
|
|
||||||
|
=item B<SECTION-GLOBAL COMMENT>
|
||||||
|
|
||||||
|
A special STIL entry that refers not to an individual SID file,
|
||||||
|
but to a whole subdirectory. These usually contain info about the
|
||||||
|
composer himself, or about all the SID file he/she ever composed,
|
||||||
|
and are always indexed in the form of "/Subdir/" (note the trailing
|
||||||
|
slash!).
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
/Hubbard_Rob/
|
||||||
|
COMMENT: All of these tunes have been confirmed by Hubbard to be his. People
|
||||||
|
have often stolen Hubbard's routine causing some tunes to be falsely
|
||||||
|
credited to him.
|
||||||
|
Hubbard's own comments are denoted by (RH).
|
||||||
|
|
||||||
|
=item B<SINGLE-TUNE ENTRY>
|
||||||
|
|
||||||
|
A STIL entry that has no tune designation in it in the form of "(#x)",
|
||||||
|
where x is a number. (Note, that a single-tune entry might still refer
|
||||||
|
to a SID file which has many tunes in it, ie. when a single-tune entry
|
||||||
|
has nothing but a COMMENT field in it!)
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
/Hubbard_Rob/Chain_Reaction.sid
|
||||||
|
TITLE: Zoolook (remix) [from Zoolook]
|
||||||
|
ARTIST: Jean Michel Jarre
|
||||||
|
|
||||||
|
Another example (the SID this is refering to has many tunes in it!):
|
||||||
|
|
||||||
|
/Barrett_Steve/Magic_Land_Dizzy.sid
|
||||||
|
COMMENT: Also used in the game "Wacky Darts" (c) 1990 Codemasters.
|
||||||
|
|
||||||
|
=item B<STIL>
|
||||||
|
|
||||||
|
SID Tune Information List, essentially a text-file database that
|
||||||
|
can be found in your HVSC in the /DOCUMENTS/ subdirectory.
|
||||||
|
|
||||||
|
=item B<STIL ENTRY>
|
||||||
|
|
||||||
|
All of the pieces of information in STIL relating to one SID file
|
||||||
|
of the HVSC. They are always indexed by the HVSC-relative pathname.
|
||||||
|
|
||||||
|
=item B<TUNE>
|
||||||
|
|
||||||
|
One of the compositions in a SID. Most SID files have only one tune
|
||||||
|
in them, but many have more than one (eg. one for the title score
|
||||||
|
of the game, and one for the hi-score music).
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
|
||||||
|
=head1 OPTIONS
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
=item B<-b>
|
||||||
|
|
||||||
|
Do B<not> print BUG entries
|
||||||
|
Default value: Not specified (ie. do print BUG entries)
|
||||||
|
|
||||||
|
Example: C<stilview -e=/Hubbard_Rob/Commando.sid -b>
|
||||||
|
|
||||||
|
When this option is specified, BUG entries will not be printed for
|
||||||
|
the given SID tune. At a minimum, the -e option has to be specified
|
||||||
|
for this option to work.
|
||||||
|
|
||||||
|
=item B<-d>
|
||||||
|
|
||||||
|
Default value: Not specified (ie. debug mode is off)
|
||||||
|
|
||||||
|
Example: C<stilview -e=/Hubbard_Rob/Commando.sid -d>
|
||||||
|
|
||||||
|
Turns on debug mode in STILView. This will result in an extensive
|
||||||
|
output, with the debugging messages going to STDERR. If you
|
||||||
|
encounter any problem or strange behavior with STILView, run
|
||||||
|
STILView with the exact same options as you did when you
|
||||||
|
encountered the problem, with this -d option added to them. Capture
|
||||||
|
the complete output of this run, and send it to me with a detailed
|
||||||
|
explanation of the problem (see email address at the top of this
|
||||||
|
file).
|
||||||
|
|
||||||
|
=item B<-e>=I<entry>
|
||||||
|
|
||||||
|
Default: NONE (you have to give an HVSC-relative pathname to this
|
||||||
|
option)
|
||||||
|
|
||||||
|
Example #1: C<stilview -e=/Hubbard_Rob/Commando.sid>
|
||||||
|
|
||||||
|
Example #2: C<stilview -e=/Hubbard_Rob/>
|
||||||
|
|
||||||
|
This is where you specify the STIL entry you are looking for, given
|
||||||
|
as an HVSC-relative pathname. If there exists no STIL entry for the
|
||||||
|
given filename, STILView will print out nothing. Otherwise, you'll
|
||||||
|
get the STIL entry (or parts of it, as you may have specified it by
|
||||||
|
other options). HVSC-relative pathnames are case-insensitive, so
|
||||||
|
/HUBBARD_ROB/Commando.sid is the same as /Hubbard_Rob/Commando.sid.
|
||||||
|
|
||||||
|
Example #1 is the most frequent way of retrieving STIL entries, and
|
||||||
|
it will return all of the STIL entry for Commando.sid, as well as
|
||||||
|
the section-global comment for /Hubbard_Rob/. Example #2 is another
|
||||||
|
valid thing to do: this will return only the section-global comment
|
||||||
|
for /Hubbard_Rob/.
|
||||||
|
|
||||||
|
=item B<-h>
|
||||||
|
|
||||||
|
Default: NONE Example: stilview -h
|
||||||
|
|
||||||
|
Prints a brief help screen listing the available options. All other
|
||||||
|
options that are also specified on the command-line are ignored.
|
||||||
|
|
||||||
|
=item B<-f>=I<field>
|
||||||
|
|
||||||
|
Default: all
|
||||||
|
|
||||||
|
Valid values for <field> are: all, name, author, title, artist,
|
||||||
|
comment
|
||||||
|
|
||||||
|
Example #1: C<stilview -l -e=/Hubbard_Rob/Delta.sid -f=comment>
|
||||||
|
|
||||||
|
Example #2: C<stilview -l -e=/Hubbard_Rob/Delta.sid -t=1 -f=title>
|
||||||
|
|
||||||
|
Example #3: C<stilview -l -e=/Hubbard_Rob/Delta.sid -t=12 -f=all -s -b>
|
||||||
|
|
||||||
|
Asks for one particular field in a STIL entry. Combined with the -t
|
||||||
|
option, these two options can retrieve any portion of a STIL entry,
|
||||||
|
including a single field in a specific subtune's entry. Below is
|
||||||
|
full and complete explanation of what the different possible
|
||||||
|
combinations of the -t and -f options retrieve:
|
||||||
|
|
||||||
|
C<-t=0 -f=all> : All of the STIL entry is printed.
|
||||||
|
|
||||||
|
C<-t=0 -f=comment> : The file-global comment is printed. For
|
||||||
|
single-tune entries that have nothing but a COMMENT field in them,
|
||||||
|
this prints that COMMENT. For single-tune entries that have other
|
||||||
|
fields in them, this prints nothing. (This is because single-tune
|
||||||
|
entries with nothing but a COMMENT field are assumed to be
|
||||||
|
file-global comments.)
|
||||||
|
|
||||||
|
C<< -t=0 -f=<name/author/title/artist> >> : Nothing is printed. This
|
||||||
|
combination of these options is invalid.
|
||||||
|
|
||||||
|
C<< -t=<x> -f=all >> : (Where x is anything but 0.) All fields from the
|
||||||
|
portion of the STIL entry for the given tune number <x> are
|
||||||
|
printed. For single-tune entries, asking for -t=1 -f=all is
|
||||||
|
equivalent to saying -t=0 -f=all, since by definition, the whole
|
||||||
|
entry refers to only one tune. (However, specifying -t with any
|
||||||
|
other number than 1 will print nothing!) Note that if there's a
|
||||||
|
file-global comment in the STIL entry (which also means that if a
|
||||||
|
single-tune entry has nothing but a COMMENT field in it), that is
|
||||||
|
B<not> printed with these combinations of options.
|
||||||
|
|
||||||
|
C<< -t=<x> -f=<name/author/title/artist/comment> >> : (Where x is anything
|
||||||
|
but 0.) The specific field from the portion of the STIL entry for
|
||||||
|
the given tune number is printed. For single-tune entries that have
|
||||||
|
nothing but a COMMENT in them, this returns nothing.
|
||||||
|
|
||||||
|
Of course, if the STIL entry or any portion of it asked with these
|
||||||
|
options does not exist, STILView will print nothing. Also, unless
|
||||||
|
otherwise specified with the -o, -s and -b options, the
|
||||||
|
section-global comment and the BUG entry of the given SID file will
|
||||||
|
also get printed (provided they exist).
|
||||||
|
|
||||||
|
In example #1, the file-global comment for /Hubbard_Rob/Delta.sid
|
||||||
|
is printed, since -t is not specified and is assumed to be 0. Also
|
||||||
|
printed are the section- global comment and the BUG entry for the
|
||||||
|
same SID file (if they exist). In example #2, the TITLE field of
|
||||||
|
the STIL entry for tune #1 of /Hubbard_Rob/Delta.sid is printed
|
||||||
|
along with the section-global comment and the BUG entry for the
|
||||||
|
same SID file (if they exist). In example #3, all of the STIL entry
|
||||||
|
for tune #12 of /Hubbard_Rob/Delta.sid is printed, but nothing
|
||||||
|
else.
|
||||||
|
|
||||||
|
=item B<-i>
|
||||||
|
|
||||||
|
Default: NONE
|
||||||
|
|
||||||
|
Example: C<stilview -i>
|
||||||
|
|
||||||
|
Starts STILView in interactive mode, ignoring all other options
|
||||||
|
specified on the command-line, except -l, -d and -m. In interactive
|
||||||
|
mode, you can look for STIL entries by typing them in. You will get
|
||||||
|
prompted for the desired STIL entry (which has to be specified with
|
||||||
|
an HVSC-relative pathname), for the tune number requested (which
|
||||||
|
should be any non-negative number, but this is not enforced), and
|
||||||
|
finally for the specific STIL field you want to retrieve.
|
||||||
|
|
||||||
|
=item B<-l>=I<HVSC base dir>
|
||||||
|
|
||||||
|
Default: The value of the HVSC_BASE environment variable
|
||||||
|
|
||||||
|
Example #1: C<stilview -l=C:\Music\HVSC\ -e=/Hubbard_Rob/Commando.sid>
|
||||||
|
|
||||||
|
Example #2: C<stilview -l=../HVSC/ =-e=/Hubbard_Rob/Commando.sid>
|
||||||
|
|
||||||
|
Example #3: C<stilview -l -e=/Hubbard_Rob/Commando.sid>
|
||||||
|
|
||||||
|
This is where you tell STILView where it can find the HVSC base
|
||||||
|
directory (the path to the directory has to be specified in the
|
||||||
|
form required by your operating system, eg. C:\Music\HVSC under
|
||||||
|
Windows, /home/lala/HVSC under UNIX). STILView will then try to
|
||||||
|
locate the STIL.txt file in the /DOCUMENTS/ subdirectory of that
|
||||||
|
directory. If this option is not specified (or if -l is specified
|
||||||
|
without a base directory), STILView will try to extract the path of
|
||||||
|
the HVSC base directory from the HVSC_BASE environment variable. If
|
||||||
|
that environment variable doesn't exist or is pointing to a
|
||||||
|
location where there's no STIL.txt file in a DOCUMENTS directory,
|
||||||
|
STILView fails. If the HVSC_BASE environment variable exists and is
|
||||||
|
valid, and this option is specified, the directory specified with
|
||||||
|
this option is used as the HVSC base directory instead of the
|
||||||
|
environment variable.
|
||||||
|
|
||||||
|
In example #1 the HVSC base directory is located in C:\Music\HVSC\
|
||||||
|
on the hard drive of a Windows PC, in example #2 it is located in
|
||||||
|
the HVSC directory of the current directory's parent directory of a
|
||||||
|
UNIX system. In example #3 the HVSC base directory is not specified
|
||||||
|
with the option, so it is assumed that the HVSC_BASE environment
|
||||||
|
variable contains the path to it. In reality, specifying the -l
|
||||||
|
option in example #3 is redundant, and can be omitted.
|
||||||
|
|
||||||
|
=item B<-m>
|
||||||
|
|
||||||
|
Demo mode
|
||||||
|
|
||||||
|
Default: NONE
|
||||||
|
|
||||||
|
Example #1: C<stilview -m>
|
||||||
|
|
||||||
|
Example #2: C<stilview -e=/Hubbard_Rob/Commando.sid -m -i>
|
||||||
|
|
||||||
|
When specified, it prints out a whole bunch of things that a) test
|
||||||
|
most of the functionality of STILView, and b) show what STILView is
|
||||||
|
capable of retrieving from STIL. In example #1, the demo is printed
|
||||||
|
with the STIL info coming from a default STIL entry, then STILView
|
||||||
|
quits. In example #2, the demo is printed taking the STIL info from
|
||||||
|
the specified STIL entry of /Hubbard_Rob/Commando.sid (instead of
|
||||||
|
the default SID file), then interactive mode is entered.
|
||||||
|
|
||||||
|
=item B<-o>
|
||||||
|
|
||||||
|
Do B<not> print STIL entries
|
||||||
|
|
||||||
|
Default value: Not specified (ie. do print STIL entries)
|
||||||
|
|
||||||
|
Example #1: C<stilview -e=/Hubbard_Rob/Delta.sid -o>
|
||||||
|
|
||||||
|
Example #2: C<stilview -e=/Hubbard_Rob/Delta.sid -o -s>
|
||||||
|
|
||||||
|
When this option is specified, STIL entries will not be printed for
|
||||||
|
the given SID tune (but section-global entries and BUG entries will
|
||||||
|
be printed, provided they exist and other options did not turn
|
||||||
|
their output off). At a minimum, the -e option has to be specified
|
||||||
|
for this option to work. Example #1 will print out the
|
||||||
|
section-global comment and the BUG entry for
|
||||||
|
/Hubbard_Rob/Delta.sid, example #2 will print out just the
|
||||||
|
section-global comment for the same SID.
|
||||||
|
|
||||||
|
=item B<-s>
|
||||||
|
|
||||||
|
Do B<not> print section-global comments
|
||||||
|
|
||||||
|
Default value: Not specified (ie. do print section-global entries)
|
||||||
|
|
||||||
|
Example: C<stilview -e=/Hubbard_Rob/Delta.sid -s>
|
||||||
|
|
||||||
|
When this option is specified, section-global entries will not be
|
||||||
|
printed for the given SID tune. At a minimum, the -e option has to
|
||||||
|
be specified for this option to work.
|
||||||
|
|
||||||
|
=item B<-t>=I<tune number>
|
||||||
|
|
||||||
|
Default value: 0
|
||||||
|
|
||||||
|
Example #1: C<stilview -e=/Hubbard_Rob/Commando.sid -t=0>
|
||||||
|
|
||||||
|
Example #2: C<stilview -e=/Hubbard_Rob/Delta.sid -t=1 -f=title -s -b>
|
||||||
|
|
||||||
|
Example #3: C<stilview -e=/Hubbard_Rob/Delta.sid -t=12>
|
||||||
|
|
||||||
|
Asks for the portion of a STIL entry referring to one particular
|
||||||
|
tune. If tune number 0 is given, it retrieves all of the entry.
|
||||||
|
Combined with the -f option, these two options can retrieve any
|
||||||
|
portion of a STIL entry, including a single field in a specific
|
||||||
|
subtune's entry.
|
||||||
|
|
||||||
|
For further details about this option, see the explanation of the
|
||||||
|
-f option.
|
||||||
|
|
||||||
|
Example #1 retrieves all of the STIL entry for
|
||||||
|
/Hubbard_Rob/Commando.sid, including the section-global comment and
|
||||||
|
the BUG entry (if any), but since the default value for this option
|
||||||
|
is 0, it might as well be omitted in this example. Example #2
|
||||||
|
retrieves only the TITLE field of the first subtune's entry for
|
||||||
|
/Hubbard_Rob/Delta.sid (and not the section- global comment or the
|
||||||
|
BUG entry), while example #3 retrieves all of the STIL entry for
|
||||||
|
tune #12 of the same SID file (including the section-global comment
|
||||||
|
and the BUG entry, if any).
|
||||||
|
|
||||||
|
=item B<-v>
|
||||||
|
|
||||||
|
Print version numbers
|
||||||
|
|
||||||
|
Default value: Not specified (ie. do *not* print version numbers)
|
||||||
|
|
||||||
|
Example #1: C<stilview -v>
|
||||||
|
|
||||||
|
Example #2: C<stilview -e=/Hubbard_Rob/Commando.sid -v>
|
||||||
|
|
||||||
|
When this option is specified, the version number of the STILView
|
||||||
|
program and the version number of the STIL.txt file used by it is
|
||||||
|
printed out. In example #1 this is the only piece of info that gets
|
||||||
|
printed on the screen, in example #2 the version numbers are
|
||||||
|
printed out, then the STIL entry for /Hubbard_Rob/Commando.sid is
|
||||||
|
also printed out.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
|
||||||
|
=head1 ENVIRONMENT
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
=item B<HVSC_BASE>
|
||||||
|
|
||||||
|
Specifies the location of the HVSC base directory.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
|
||||||
|
=head1 EXAMPLES
|
||||||
|
|
||||||
|
All of the examples below assume that the HVSC_BASE environment is set
|
||||||
|
to a valid HVSC base directory (where the F<$HVSC_BASE/DOCUMENTS/STIL.txt>
|
||||||
|
and F<$HVSC_BASE/DOCUMENTS/BUGlist.txt> files exist), and the examples
|
||||||
|
also assume the presence of the following entries in these files:
|
||||||
|
|
||||||
|
--- In STIL.txt ---
|
||||||
|
|
||||||
|
/Hubbard_Rob/
|
||||||
|
COMMENT: All of these tunes have been confirmed by Hubbard to be his. People
|
||||||
|
have often stolen Hubbard's routine causing some tunes to be falsely
|
||||||
|
credited to him.
|
||||||
|
|
||||||
|
/Hubbard_Rob/Action_Biker.sid
|
||||||
|
COMMENT: "Action B was a very early game and very conservative in it's approach
|
||||||
|
- it was my idea of giving them what I thought they wanted, a simple
|
||||||
|
cute tune....." (RH)
|
||||||
|
|
||||||
|
/Hubbard_Rob/Commando.sid
|
||||||
|
COMMENT: Tunes #1 and #3 have been converted from arcade version.
|
||||||
|
|
||||||
|
/Hubbard_Rob/Delta.sid
|
||||||
|
COMMENT: According to Hubbard, Kentilla and Delta were the most complicated one
|
||||||
|
to compose, they took the longest time to do and they both drove him
|
||||||
|
insane.
|
||||||
|
(#1)
|
||||||
|
TITLE: On the Run [from the Dark Side of the Moon]
|
||||||
|
ARTIST: Pink Floyd
|
||||||
|
COMMENT: It is more inspired by it than a remix of it.
|
||||||
|
(#12)
|
||||||
|
TITLE: Koyaanisqatsi [from the movie]
|
||||||
|
ARTIST: Philip Glass
|
||||||
|
COMMENT: "Inspired by Philip Glass and Pink Floyd." (RH)
|
||||||
|
|
||||||
|
/Hubbard_Rob/International_Karate.sid
|
||||||
|
TITLE: Merry Christmas, Mr. Lawrence [from the movie] (0:42-1:16)
|
||||||
|
ARTIST: Ryuichi Sakamoto
|
||||||
|
COMMENT: "[...] I started exploring pentatonic things in B flat minor over
|
||||||
|
different bass notes, B flat, D flat, G flat and A flat. The middle
|
||||||
|
section went into F (I think) at double tempo to liven things up. I
|
||||||
|
was pleased with the tune......" (RH)
|
||||||
|
|
||||||
|
/Hubbard_Rob/Rasputin.sid
|
||||||
|
(#1)
|
||||||
|
TITLE: Katjusha (0:07-0:36)
|
||||||
|
ARTIST: Matvei Blanter, M. Isakovski
|
||||||
|
TITLE: Katjusha (2:20)
|
||||||
|
ARTIST: Matvei Blanter, M. Isakovski
|
||||||
|
TITLE: Kaljinka (2:41-2:51)
|
||||||
|
ARTIST: Traditional
|
||||||
|
COMMENT: Russian folk song.
|
||||||
|
TITLE: Kaljinka (3:12-3:22)
|
||||||
|
ARTIST: Traditional
|
||||||
|
COMMENT: Russian folk song.
|
||||||
|
(#2)
|
||||||
|
COMMENT: Russian folk song.
|
||||||
|
|
||||||
|
--- In BUGlist.txt ---
|
||||||
|
|
||||||
|
/Hubbard_Rob/Commando.sid
|
||||||
|
BUG: This is just for demo.
|
||||||
|
|
||||||
|
/Hubbard_Rob/Delta.sid
|
||||||
|
(#12)
|
||||||
|
BUG: Demo entry.
|
||||||
|
|
||||||
|
Given these entries, following are the printouts you can expect from
|
||||||
|
STILView. ($> denotes a command-line prompt given by your operating
|
||||||
|
system.)
|
||||||
|
|
||||||
|
Everything related to a SID file is printed:
|
||||||
|
|
||||||
|
$> stilview -e=/Hubbard_Rob/Commando.sid
|
||||||
|
---- GLOBAL COMMENT ----
|
||||||
|
COMMENT: All of these tunes have been confirmed by Hubbard to be his. People
|
||||||
|
have often stolen Hubbard's routine causing some tunes to be falsely
|
||||||
|
credited to him.
|
||||||
|
------ STIL ENTRY ------
|
||||||
|
COMMENT: Tunes #1 and #3 have been converted from arcade version.
|
||||||
|
---------- BUG ----------
|
||||||
|
BUG: This is just for demo.
|
||||||
|
$>
|
||||||
|
|
||||||
|
Ask for just the section-global comment:
|
||||||
|
|
||||||
|
$> stilview -e=/Hubbard_Rob/
|
||||||
|
/Hubbard_Rob/
|
||||||
|
COMMENT: All of these tunes have been confirmed by Hubbard to be his. People
|
||||||
|
have often stolen Hubbard's routine causing some tunes to be falsely
|
||||||
|
credited to him.
|
||||||
|
$>
|
||||||
|
|
||||||
|
Note that this can also be retrieved with:
|
||||||
|
|
||||||
|
$> stilview -e=/Hubbard_Rob/Commando.sid -o -b
|
||||||
|
COMMENT: All of these tunes have been confirmed by Hubbard to be his. People
|
||||||
|
have often stolen Hubbard's routine causing some tunes to be falsely
|
||||||
|
credited to him.
|
||||||
|
$>
|
||||||
|
|
||||||
|
This prints out nothing, as single-tune entries do not have file-global
|
||||||
|
comments:
|
||||||
|
|
||||||
|
$> stilview -e=/Hubbard_Rob/International_Karate.sid -t=0 -f=comment -s -b
|
||||||
|
$>
|
||||||
|
|
||||||
|
...Except if the only field in them is a COMMENT (in which case that
|
||||||
|
comment is assumed to be a file-global comment):
|
||||||
|
|
||||||
|
$> stilview -e=/Hubbard_Rob/Action_Biker.sid -t=0 -f=comment -s -b
|
||||||
|
COMMENT: "Action B was a very early game and very conservative in it's approach
|
||||||
|
- it was my idea of giving them what I thought they wanted, a simple
|
||||||
|
cute tune....." (RH)
|
||||||
|
$>
|
||||||
|
|
||||||
|
Also note that single-tune entries have only one tune, so asking for
|
||||||
|
the STIL entry of tune #3 is pointless:
|
||||||
|
|
||||||
|
$> stilview -e=/Hubbard_Rob/International_Karate.sid -t=3 -s -b
|
||||||
|
$>
|
||||||
|
|
||||||
|
Print out the file-global comment for the given SID file:
|
||||||
|
|
||||||
|
$> stilview -e=/Hubbard_Rob/Delta.sid -t=0 -f=comment -s -b
|
||||||
|
COMMENT: According to Hubbard, Kentilla and Delta were the most complicated one
|
||||||
|
to compose, they took the longest time to do and they both drove him
|
||||||
|
insane.
|
||||||
|
$>
|
||||||
|
|
||||||
|
Print out the ARTIST field of tune #12 of the given SID file, plus
|
||||||
|
print out everything else related to the SID file:
|
||||||
|
|
||||||
|
$> stilview -e=/Hubbard_Rob/Delta.sid -t=12 -f=artist
|
||||||
|
---- GLOBAL COMMENT ----
|
||||||
|
COMMENT: All of these tunes have been confirmed by Hubbard to be his. People
|
||||||
|
have often stolen Hubbard's routine causing some tunes to be falsely
|
||||||
|
credited to him.
|
||||||
|
------ STIL ENTRY ------
|
||||||
|
ARTIST: Philip Glass
|
||||||
|
---------- BUG ----------
|
||||||
|
BUG: Demo entry.
|
||||||
|
$>
|
||||||
|
|
||||||
|
Note that the current version of STILView is capable to retrieve only
|
||||||
|
the first specified field of a tune that covers multiple songs! See
|
||||||
|
below:
|
||||||
|
|
||||||
|
$> stilview -e=/Hubbard_Rob/Rasputin.sid -t=1 -f=title -s
|
||||||
|
TITLE: Katjusha (0:07-0:36)
|
||||||
|
$>
|
||||||
|
|
||||||
|
Section-global comments are printed out even if the STIL entry for the
|
||||||
|
given SID file does not exist:
|
||||||
|
|
||||||
|
$> stilview -e=/Hubbard_Rob/This_doesnt_exist.sid
|
||||||
|
COMMENT: All of these tunes have been confirmed by Hubbard to be his. People
|
||||||
|
have often stolen Hubbard's routine causing some tunes to be falsely
|
||||||
|
credited to him.
|
||||||
|
$>
|
||||||
|
|
||||||
|
The following 4 steps depict how to have STILView print out everything
|
||||||
|
related to a given SID file's given tune number one by one:
|
||||||
|
|
||||||
|
1) This prints out just the section-global comment:
|
||||||
|
|
||||||
|
$> stilview -e=/Hubbard_Rob/Delta.sid -o -b
|
||||||
|
COMMENT: All of these tunes have been confirmed by Hubbard to be his. People
|
||||||
|
have often stolen Hubbard's routine causing some tunes to be falsely
|
||||||
|
credited to him.
|
||||||
|
$>
|
||||||
|
|
||||||
|
2) This prints out just the file-global comment:
|
||||||
|
|
||||||
|
$> stilview -e=/Hubbard_Rob/Delta.sid -t=0 -f=comment -s -b
|
||||||
|
COMMENT: According to Hubbard, Kentilla and Delta were the most complicated one
|
||||||
|
to compose, they took the longest time to do and they both drove him
|
||||||
|
insane.
|
||||||
|
$>
|
||||||
|
|
||||||
|
3) This prints out all of the STIL entry for the given tune number:
|
||||||
|
|
||||||
|
$> stilview -e=/Hubbard_Rob/Delta.sid -t=12 -f=all -s -b
|
||||||
|
TITLE: Koyaanisqatsi [from the movie]
|
||||||
|
ARTIST: Philip Glass
|
||||||
|
COMMENT: "Inspired by Philip Glass and Pink Floyd." (RH)
|
||||||
|
$>
|
||||||
|
|
||||||
|
4) And this prints out just the BUG entry for the same tune number:
|
||||||
|
|
||||||
|
$> stilview -e=/Hubbard_Rob/Delta.sid -t=12 -s -o
|
||||||
|
BUG: Demo entry.
|
||||||
|
$>
|
||||||
|
|
||||||
|
The following 3 steps depict how to have STILView print out everything
|
||||||
|
related to a given SID file:
|
||||||
|
|
||||||
|
1) This prints out just the section-global comment:
|
||||||
|
|
||||||
|
$> stilview -e=/Hubbard_Rob/Delta.sid -o -b
|
||||||
|
COMMENT: All of these tunes have been confirmed by Hubbard to be his. People
|
||||||
|
have often stolen Hubbard's routine causing some tunes to be falsely
|
||||||
|
credited to him.
|
||||||
|
$>
|
||||||
|
|
||||||
|
2) This prints out all of the STIL entry:
|
||||||
|
|
||||||
|
$> stilview -e=/Hubbard_Rob/Delta.sid -s -b
|
||||||
|
COMMENT: "[...] The Delta music loader and ingame music was Gary Liddon's idea.
|
||||||
|
[...] He was the producer at Thalamus at the time. He told Rob Hubbard
|
||||||
|
to make the ingame music like the 2nd track from Dark Side of the Moon
|
||||||
|
by Pink Floyd." (Info from Matt Furniss.)
|
||||||
|
"The small jingles are all small clips from Sanxion and Romeo/Juliet
|
||||||
|
music. They were all supposed to be for short stingers such as end of
|
||||||
|
level, extra life etc..."
|
||||||
|
"Delta was based on this minimalist composition technique inspired by
|
||||||
|
Glass and a bit of Pink Floyd. It was quite hard too do and required
|
||||||
|
some custom code to the driver to do it. The music was tedious to
|
||||||
|
debug. The other Delta stuff was more conventional - I quite liked the
|
||||||
|
other tunes. Delta was spread over a 2 week period....." (RH)
|
||||||
|
According to Hubbard, Kentilla and Delta were the most complicated one
|
||||||
|
to compose, they took the longest time to do and they both drove him
|
||||||
|
insane.
|
||||||
|
(#1)
|
||||||
|
TITLE: On the Run [from the Dark Side of the Moon]
|
||||||
|
ARTIST: Pink Floyd
|
||||||
|
COMMENT: It is more inspired by it than a remix of it.
|
||||||
|
(#12)
|
||||||
|
TITLE: Koyaanisqatsi [from the movie]
|
||||||
|
ARTIST: Philip Glass
|
||||||
|
COMMENT: "Inspired by Philip Glass and Pink Floyd." (RH)
|
||||||
|
$>
|
||||||
|
|
||||||
|
3) And this prints out all of the BUG entry:
|
||||||
|
|
||||||
|
$> stilview -e=/Hubbard_Rob/Delta.sid -s -o
|
||||||
|
(#12)
|
||||||
|
BUG: Demo entry.
|
||||||
|
$>
|
||||||
|
|
||||||
|
|
||||||
|
=head1 AUTHORS
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
=item B<LaLa> <LaLa@C64.org>
|
||||||
|
|
||||||
|
Original author.
|
||||||
|
|
||||||
|
=item B<Leandro Nini> <drfiemost@users.sourceforge.net>
|
||||||
|
|
||||||
|
Current maintainer.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
|
||||||
|
=head1 RESOURCES
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
=item SourceForge project: L<http://sourceforge.net/projects/sidplay-residfp/>
|
||||||
|
|
||||||
|
=item High Voltage Sid Collection (HVSC): L<http://hvsc.c64.org/>
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
|
||||||
|
=head1 COPYING
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
=item Copyright (C) 1998, 2002 LaLa
|
||||||
|
|
||||||
|
=item Copyright (C) 2012-2014 Leandro Nini
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
@ -0,0 +1,337 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2011-2013 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
* Copyright 2007-2010 Antti Lankila
|
||||||
|
* Copyright 2000 Simon White
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OPCODES_H
|
||||||
|
#define OPCODES_H
|
||||||
|
|
||||||
|
#define OPCODE_MAX 0x100
|
||||||
|
|
||||||
|
/* HLT
|
||||||
|
case 0x02: case 0x12: case 0x22: case 0x32: case 0x42: case 0x52:
|
||||||
|
case 0x62: case 0x72: case 0x92: case 0xb2: case 0xd2: case 0xf2:
|
||||||
|
case 0x02: case 0x12: case 0x22: case 0x32: case 0x42: case 0x52:
|
||||||
|
case 0x62: case 0x72: case 0x92: case 0xb2: case 0xd2: case 0xf2:
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define BRKn 0x00
|
||||||
|
#define JSRw 0x20
|
||||||
|
#define RTIn 0x40
|
||||||
|
#define RTSn 0x60
|
||||||
|
#define NOPb 0x80
|
||||||
|
#define NOPb_ NOPb: case 0x82: case 0xC2: case 0xE2: case 0x89
|
||||||
|
#define LDYb 0xA0
|
||||||
|
#define CPYb 0xC0
|
||||||
|
#define CPXb 0xE0
|
||||||
|
|
||||||
|
#define ORAix 0x01
|
||||||
|
#define ANDix 0x21
|
||||||
|
#define EORix 0x41
|
||||||
|
#define ADCix 0x61
|
||||||
|
#define STAix 0x81
|
||||||
|
#define LDAix 0xA1
|
||||||
|
#define CMPix 0xC1
|
||||||
|
#define SBCix 0xE1
|
||||||
|
|
||||||
|
#define LDXb 0xA2
|
||||||
|
|
||||||
|
#define SLOix 0x03
|
||||||
|
#define RLAix 0x23
|
||||||
|
#define SREix 0x43
|
||||||
|
#define RRAix 0x63
|
||||||
|
#define SAXix 0x83
|
||||||
|
#define LAXix 0xA3
|
||||||
|
#define DCPix 0xC3
|
||||||
|
#define ISBix 0xE3
|
||||||
|
|
||||||
|
#define NOPz 0x04
|
||||||
|
#define NOPz_ NOPz: case 0x44: case 0x64
|
||||||
|
#define BITz 0x24
|
||||||
|
#define STYz 0x84
|
||||||
|
#define LDYz 0xA4
|
||||||
|
#define CPYz 0xC4
|
||||||
|
#define CPXz 0xE4
|
||||||
|
|
||||||
|
#define ORAz 0x05
|
||||||
|
#define ANDz 0x25
|
||||||
|
#define EORz 0x45
|
||||||
|
#define ADCz 0x65
|
||||||
|
#define STAz 0x85
|
||||||
|
#define LDAz 0xA5
|
||||||
|
#define CMPz 0xC5
|
||||||
|
#define SBCz 0xE5
|
||||||
|
|
||||||
|
#define ASLz 0x06
|
||||||
|
#define ROLz 0x26
|
||||||
|
#define LSRz 0x46
|
||||||
|
#define RORz 0x66
|
||||||
|
#define STXz 0x86
|
||||||
|
#define LDXz 0xA6
|
||||||
|
#define DECz 0xC6
|
||||||
|
#define INCz 0xE6
|
||||||
|
|
||||||
|
#define SLOz 0x07
|
||||||
|
#define RLAz 0x27
|
||||||
|
#define SREz 0x47
|
||||||
|
#define RRAz 0x67
|
||||||
|
#define SAXz 0x87
|
||||||
|
#define LAXz 0xA7
|
||||||
|
#define DCPz 0xC7
|
||||||
|
#define ISBz 0xE7
|
||||||
|
|
||||||
|
#define PHPn 0x08
|
||||||
|
#define PLPn 0x28
|
||||||
|
#define PHAn 0x48
|
||||||
|
#define PLAn 0x68
|
||||||
|
#define DEYn 0x88
|
||||||
|
#define TAYn 0xA8
|
||||||
|
#define INYn 0xC8
|
||||||
|
#define INXn 0xE8
|
||||||
|
|
||||||
|
#define ORAb 0x09
|
||||||
|
#define ANDb 0x29
|
||||||
|
#define EORb 0x49
|
||||||
|
#define ADCb 0x69
|
||||||
|
#define LDAb 0xA9
|
||||||
|
#define CMPb 0xC9
|
||||||
|
#define SBCb 0xE9
|
||||||
|
#define SBCb_ SBCb: case 0XEB
|
||||||
|
|
||||||
|
#define ASLn 0x0A
|
||||||
|
#define ROLn 0x2A
|
||||||
|
#define LSRn 0x4A
|
||||||
|
#define RORn 0x6A
|
||||||
|
#define TXAn 0x8A
|
||||||
|
#define TAXn 0xAA
|
||||||
|
#define DEXn 0xCA
|
||||||
|
#define NOPn 0xEA
|
||||||
|
#define NOPn_ NOPn: case 0x1A: case 0x3A: case 0x5A: case 0x7A: case 0xDA: case 0xFA
|
||||||
|
|
||||||
|
#define ANCb 0x0B
|
||||||
|
#define ANCb_ ANCb: case 0x2B
|
||||||
|
#define ASRb 0x4B
|
||||||
|
#define ARRb 0x6B
|
||||||
|
#define ANEb 0x8B
|
||||||
|
#define XAAb 0x8B
|
||||||
|
#define LXAb 0xAB
|
||||||
|
#define SBXb 0xCB
|
||||||
|
|
||||||
|
#define NOPa 0x0C
|
||||||
|
#define BITa 0x2C
|
||||||
|
#define JMPw 0x4C
|
||||||
|
#define JMPi 0x6C
|
||||||
|
#define STYa 0x8C
|
||||||
|
#define LDYa 0xAC
|
||||||
|
#define CPYa 0xCC
|
||||||
|
#define CPXa 0xEC
|
||||||
|
|
||||||
|
#define ORAa 0x0D
|
||||||
|
#define ANDa 0x2D
|
||||||
|
#define EORa 0x4D
|
||||||
|
#define ADCa 0x6D
|
||||||
|
#define STAa 0x8D
|
||||||
|
#define LDAa 0xAD
|
||||||
|
#define CMPa 0xCD
|
||||||
|
#define SBCa 0xED
|
||||||
|
|
||||||
|
#define ASLa 0x0E
|
||||||
|
#define ROLa 0x2E
|
||||||
|
#define LSRa 0x4E
|
||||||
|
#define RORa 0x6E
|
||||||
|
#define STXa 0x8E
|
||||||
|
#define LDXa 0xAE
|
||||||
|
#define DECa 0xCE
|
||||||
|
#define INCa 0xEE
|
||||||
|
|
||||||
|
#define SLOa 0x0F
|
||||||
|
#define RLAa 0x2F
|
||||||
|
#define SREa 0x4F
|
||||||
|
#define RRAa 0x6F
|
||||||
|
#define SAXa 0x8F
|
||||||
|
#define LAXa 0xAF
|
||||||
|
#define DCPa 0xCF
|
||||||
|
#define ISBa 0xEF
|
||||||
|
|
||||||
|
#define BPLr 0x10
|
||||||
|
#define BMIr 0x30
|
||||||
|
#define BVCr 0x50
|
||||||
|
#define BVSr 0x70
|
||||||
|
#define BCCr 0x90
|
||||||
|
#define BCSr 0xB0
|
||||||
|
#define BNEr 0xD0
|
||||||
|
#define BEQr 0xF0
|
||||||
|
|
||||||
|
#define ORAiy 0x11
|
||||||
|
#define ANDiy 0x31
|
||||||
|
#define EORiy 0x51
|
||||||
|
#define ADCiy 0x71
|
||||||
|
#define STAiy 0x91
|
||||||
|
#define LDAiy 0xB1
|
||||||
|
#define CMPiy 0xD1
|
||||||
|
#define SBCiy 0xF1
|
||||||
|
|
||||||
|
#define SLOiy 0x13
|
||||||
|
#define RLAiy 0x33
|
||||||
|
#define SREiy 0x53
|
||||||
|
#define RRAiy 0x73
|
||||||
|
#define SHAiy 0x93
|
||||||
|
#define LAXiy 0xB3
|
||||||
|
#define DCPiy 0xD3
|
||||||
|
#define ISBiy 0xF3
|
||||||
|
|
||||||
|
#define NOPzx 0x14
|
||||||
|
#define NOPzx_ NOPzx: case 0x34: case 0x54: case 0x74: case 0xD4: case 0xF4
|
||||||
|
#define STYzx 0x94
|
||||||
|
#define LDYzx 0xB4
|
||||||
|
|
||||||
|
#define ORAzx 0x15
|
||||||
|
#define ANDzx 0x35
|
||||||
|
#define EORzx 0x55
|
||||||
|
#define ADCzx 0x75
|
||||||
|
#define STAzx 0x95
|
||||||
|
#define LDAzx 0xB5
|
||||||
|
#define CMPzx 0xD5
|
||||||
|
#define SBCzx 0xF5
|
||||||
|
|
||||||
|
#define ASLzx 0x16
|
||||||
|
#define ROLzx 0x36
|
||||||
|
#define LSRzx 0x56
|
||||||
|
#define RORzx 0x76
|
||||||
|
#define STXzy 0x96
|
||||||
|
#define LDXzy 0xB6
|
||||||
|
#define DECzx 0xD6
|
||||||
|
#define INCzx 0xF6
|
||||||
|
|
||||||
|
#define SLOzx 0x17
|
||||||
|
#define RLAzx 0x37
|
||||||
|
#define SREzx 0x57
|
||||||
|
#define RRAzx 0x77
|
||||||
|
#define SAXzy 0x97
|
||||||
|
#define LAXzy 0xB7
|
||||||
|
#define DCPzx 0xD7
|
||||||
|
#define ISBzx 0xF7
|
||||||
|
|
||||||
|
#define CLCn 0x18
|
||||||
|
#define SECn 0x38
|
||||||
|
#define CLIn 0x58
|
||||||
|
#define SEIn 0x78
|
||||||
|
#define TYAn 0x98
|
||||||
|
#define CLVn 0xB8
|
||||||
|
#define CLDn 0xD8
|
||||||
|
#define SEDn 0xF8
|
||||||
|
|
||||||
|
#define ORAay 0x19
|
||||||
|
#define ANDay 0x39
|
||||||
|
#define EORay 0x59
|
||||||
|
#define ADCay 0x79
|
||||||
|
#define STAay 0x99
|
||||||
|
#define LDAay 0xB9
|
||||||
|
#define CMPay 0xD9
|
||||||
|
#define SBCay 0xF9
|
||||||
|
|
||||||
|
#define TXSn 0x9A
|
||||||
|
#define TSXn 0xBA
|
||||||
|
|
||||||
|
#define SLOay 0x1B
|
||||||
|
#define RLAay 0x3B
|
||||||
|
#define SREay 0x5B
|
||||||
|
#define RRAay 0x7B
|
||||||
|
#define SHSay 0x9B
|
||||||
|
#define TASay 0x9B
|
||||||
|
#define LASay 0xBB
|
||||||
|
#define DCPay 0xDB
|
||||||
|
#define ISBay 0xFB
|
||||||
|
|
||||||
|
#define NOPax 0x1C
|
||||||
|
#define NOPax_ NOPax: case 0x3C: case 0x5C: case 0x7C: case 0xDC: case 0xFC
|
||||||
|
#define SHYax 0x9C
|
||||||
|
#define LDYax 0xBC
|
||||||
|
|
||||||
|
#define ORAax 0x1D
|
||||||
|
#define ANDax 0x3D
|
||||||
|
#define EORax 0x5D
|
||||||
|
#define ADCax 0x7D
|
||||||
|
#define STAax 0x9D
|
||||||
|
#define LDAax 0xBD
|
||||||
|
#define CMPax 0xDD
|
||||||
|
#define SBCax 0xFD
|
||||||
|
|
||||||
|
#define ASLax 0x1E
|
||||||
|
#define ROLax 0x3E
|
||||||
|
#define LSRax 0x5E
|
||||||
|
#define RORax 0x7E
|
||||||
|
#define SHXay 0x9E
|
||||||
|
#define LDXay 0xBE
|
||||||
|
#define DECax 0xDE
|
||||||
|
#define INCax 0xFE
|
||||||
|
|
||||||
|
#define SLOax 0x1F
|
||||||
|
#define RLAax 0x3F
|
||||||
|
#define SREax 0x5F
|
||||||
|
#define RRAax 0x7F
|
||||||
|
#define SHAay 0x9F
|
||||||
|
#define LAXay 0xBF
|
||||||
|
#define DCPax 0xDF
|
||||||
|
#define ISBax 0xFF
|
||||||
|
|
||||||
|
// Instruction Aliases
|
||||||
|
#define ASOix SLOix
|
||||||
|
#define LSEix SREix
|
||||||
|
#define AXSix SAXix
|
||||||
|
#define DCMix DCPix
|
||||||
|
#define INSix ISBix
|
||||||
|
#define ASOz SLOz
|
||||||
|
#define LSEz SREz
|
||||||
|
#define AXSz SAXz
|
||||||
|
#define DCMz DCPz
|
||||||
|
#define INSz ISBz
|
||||||
|
#define ALRb ASRb
|
||||||
|
#define OALb LXAb
|
||||||
|
#define ASOa SLOa
|
||||||
|
#define LSEa SREa
|
||||||
|
#define AXSa SAXa
|
||||||
|
#define DCMa DCPa
|
||||||
|
#define INSa ISBa
|
||||||
|
#define ASOiy SLOiy
|
||||||
|
#define LSEiy SREiy
|
||||||
|
#define AXAiy SHAiy
|
||||||
|
#define DCMiy DCPiy
|
||||||
|
#define INSiy ISBiy
|
||||||
|
#define ASOzx SLOzx
|
||||||
|
#define LSEzx SREzx
|
||||||
|
#define AXSzy SAXzy
|
||||||
|
#define DCMzx DCPzx
|
||||||
|
#define INSzx ISBzx
|
||||||
|
#define ASOay SLOay
|
||||||
|
#define LSEay SREay
|
||||||
|
#define DCMay DCPay
|
||||||
|
#define INSay ISBay
|
||||||
|
#define SAYax SHYax
|
||||||
|
#define XASay SHXay
|
||||||
|
#define ASOax SLOax
|
||||||
|
#define LSEax SREax
|
||||||
|
#define AXAay SHAay
|
||||||
|
#define DCMax DCPax
|
||||||
|
#define INSax ISBax
|
||||||
|
#define SKBn NOPb
|
||||||
|
#define SKWn NOPa
|
||||||
|
|
||||||
|
#endif // OPCODES_H
|
Binary file not shown.
|
@ -0,0 +1,35 @@
|
||||||
|
/* SidTuneCfg.h (template) */
|
||||||
|
|
||||||
|
#ifndef SIDTUNECFG_H
|
||||||
|
#define SIDTUNECFG_H
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Minimum load address for real c64 only tunes */
|
||||||
|
#define SIDTUNE_R64_MIN_LOAD_ADDR 0x07e8
|
||||||
|
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
* Don't touch these!
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#undef SIDTUNE_NO_STDIN_LOADER
|
||||||
|
#undef SIDTUNE_REJECT_UNKNOWN_FIELDS
|
||||||
|
|
||||||
|
|
||||||
|
/* Define the file/path separator(s) that your filesystem uses:
|
||||||
|
SID_FS_IS_COLON_AND_BACKSLASH, SID_FS_IS_COLON_AND_SLASH,
|
||||||
|
SID_FS_IS_BACKSLASH, SID_FS_IS_COLON, SID_FS_IS_SLASH */
|
||||||
|
#if defined(_WIN32) || defined(_MSDOS) || defined(_OS2)
|
||||||
|
#define SID_FS_IS_COLON_AND_BACKSLASH_AND_SLASH
|
||||||
|
#elif defined(__APPLE__) && defined(__MACH__)
|
||||||
|
#define SID_FS_IS_COLON
|
||||||
|
#elif defined(AMIGA)
|
||||||
|
#define SID_FS_IS_COLON_AND_SLASH
|
||||||
|
#else
|
||||||
|
#define SID_FS_IS_SLASH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SIDTUNECFG_H */
|
Binary file not shown.
|
@ -0,0 +1,89 @@
|
||||||
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
|
AC_INIT([sidplayfp], [1.4.0alpha], [], [], [http://sourceforge.net/projects/sidplay-residfp/])
|
||||||
|
AC_CONFIG_SRCDIR([src/main.cpp])
|
||||||
|
AC_CONFIG_AUX_DIR([build-aux])
|
||||||
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
AC_CONFIG_HEADERS([config.h])
|
||||||
|
AM_INIT_AUTOMAKE
|
||||||
|
|
||||||
|
|
||||||
|
AC_CANONICAL_HOST
|
||||||
|
|
||||||
|
AC_PROG_RANLIB
|
||||||
|
|
||||||
|
dnl Checks for programs.
|
||||||
|
AC_PROG_CXX
|
||||||
|
|
||||||
|
dnl Use C++ for tests.
|
||||||
|
AC_LANG([C++])
|
||||||
|
|
||||||
|
|
||||||
|
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
AC_C_BIGENDIAN
|
||||||
|
|
||||||
|
|
||||||
|
dnl Audio subsystem
|
||||||
|
|
||||||
|
AUDIO_LDFLAGS=""
|
||||||
|
|
||||||
|
PKG_CHECK_MODULES(ALSA,
|
||||||
|
[alsa >= 1.0],
|
||||||
|
[AC_DEFINE([HAVE_ALSA], 1, [Define to 1 if you have libasound (-lasound).])],
|
||||||
|
[AC_MSG_WARN([$ALSA_PKG_ERRORS])]
|
||||||
|
)
|
||||||
|
|
||||||
|
PKG_CHECK_MODULES(PULSE,
|
||||||
|
[libpulse-simple >= 1.0],
|
||||||
|
[AC_DEFINE([HAVE_PULSE], 1, [Define to 1 if you have libpulse-simple (-lpulse-simple).])],
|
||||||
|
[AC_MSG_WARN([$PULSE_PKG_ERRORS])]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
dnl Checks what version of Unix we have and soundcard support
|
||||||
|
AC_CHECK_HEADERS([sys/ioctl.h linux/soundcard.h machine/soundcard.h \
|
||||||
|
sys/soundcard.h soundcard.h])
|
||||||
|
|
||||||
|
AC_CHECK_HEADERS([dsound.h mmsystem.h], [], [], [#include <windows.h>])
|
||||||
|
|
||||||
|
AS_IF([test "$ac_cv_header_dsound_h" = "yes"],
|
||||||
|
[AUDIO_LDFLAGS="$AUDIO_LDFLAGS -ldsound -ldxguid"]
|
||||||
|
)
|
||||||
|
|
||||||
|
AS_IF([test "$ac_cv_header_mmsystem_h" = "yes"],
|
||||||
|
[AUDIO_LDFLAGS="$AUDIO_LDFLAGS -lwinmm"]
|
||||||
|
)
|
||||||
|
|
||||||
|
# NetBSD/OpenBSD OSS audio emulation
|
||||||
|
AS_IF([test "x$ac_cv_header_soundcard_h" = "xyes"],
|
||||||
|
[AUDIO_LDFLAGS="$AUDIO_LDFLAGS -lossaudio"]
|
||||||
|
)
|
||||||
|
|
||||||
|
AC_SUBST(AUDIO_LDFLAGS)
|
||||||
|
|
||||||
|
AC_CHECK_FUNCS([strncasecmp strcasecmp])
|
||||||
|
|
||||||
|
PKG_CHECK_MODULES(SIDPLAYFP, [libsidplayfp >= 1.0])
|
||||||
|
PKG_CHECK_MODULES(STILVIEW, [libstilview >= 1.0])
|
||||||
|
|
||||||
|
# hack?
|
||||||
|
saveCPPFLAGS=$CPPFLAGS
|
||||||
|
CPPFLAGS="$CPPFLAGS $SIDPLAYFP_CFLAGS"
|
||||||
|
|
||||||
|
AC_CHECK_HEADERS([sidplayfp/builders/residfp.h sidplayfp/builders/resid.h sidplayfp/builders/hardsid.h])
|
||||||
|
|
||||||
|
CPPFLAGS=$saveCPPFLAGS
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([for debugging])
|
||||||
|
AC_ARG_ENABLE(debug, [AS_HELP_STRING([--enable-debug], [compile for debugging @<:@no/yes, default=no@:>@])],
|
||||||
|
[], [enable_debug=no])
|
||||||
|
|
||||||
|
AS_IF([test "x$enable_debug" = "xno"],
|
||||||
|
[AC_MSG_RESULT([Build without debugging messages]); debug_flags=-DNDEBUG]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
AC_CONFIG_FILES([
|
||||||
|
Makefile
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_OUTPUT
|
|
@ -0,0 +1,37 @@
|
||||||
|
0x01, 0x00, 0x6f, 0x36, 0x35, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0xcf, 0x00, 0x00, 0x04, 0x00, 0x00,
|
||||||
|
0x00, 0x40, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x1b, 0x10, 0xc5, 0x10, 0xce,
|
||||||
|
0x10, 0xce, 0x10, 0x8c, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x6c, 0x0e, 0x10, 0x6c, 0x0c, 0x10, 0x78, 0xa9,
|
||||||
|
0x00, 0x8d, 0x1a, 0xd0, 0xad, 0x19, 0xd0, 0x8d,
|
||||||
|
0x19, 0xd0, 0xa9, 0x7f, 0x8d, 0x0d, 0xdc, 0x8d,
|
||||||
|
0x0d, 0xdd, 0xad, 0x0d, 0xdc, 0xad, 0x0d, 0xdd,
|
||||||
|
0xa9, 0x0f, 0x8d, 0x18, 0xd4, 0xad, 0x12, 0x10,
|
||||||
|
0xf0, 0x07, 0xa2, 0x25, 0xa0, 0x40, 0x4c, 0x4a,
|
||||||
|
0x10, 0xa2, 0x95, 0xa0, 0x42, 0x8e, 0x04, 0xdc,
|
||||||
|
0x8c, 0x05, 0xdc, 0xa2, 0x9b, 0xa0, 0x37, 0x4d,
|
||||||
|
0x13, 0x10, 0x0d, 0x10, 0x10, 0xf0, 0x04, 0xa2,
|
||||||
|
0x1b, 0xa0, 0x00, 0x8e, 0x11, 0xd0, 0x8c, 0x12,
|
||||||
|
0xd0, 0xad, 0x10, 0x10, 0xf0, 0x0a, 0xad, 0x11,
|
||||||
|
0x10, 0xf0, 0x05, 0xa2, 0xb2, 0x8e, 0x14, 0x03,
|
||||||
|
0xad, 0x0b, 0x10, 0xd0, 0x08, 0xa9, 0x81, 0x8d,
|
||||||
|
0x1a, 0xd0, 0x4c, 0x8c, 0x10, 0xa9, 0x81, 0xa2,
|
||||||
|
0x01, 0x8d, 0x0d, 0xdc, 0x8e, 0x0e, 0xdc, 0xad,
|
||||||
|
0x10, 0x10, 0xd0, 0x02, 0xa9, 0x37, 0x85, 0x01,
|
||||||
|
0xad, 0x14, 0x10, 0x48, 0xad, 0x0a, 0x10, 0x28,
|
||||||
|
0x20, 0x18, 0x10, 0xad, 0x10, 0x10, 0xf0, 0x0a,
|
||||||
|
0xad, 0x11, 0x10, 0xf0, 0x04, 0xa9, 0x37, 0x85,
|
||||||
|
0x01, 0x58, 0x4c, 0xaf, 0x10, 0xa5, 0x01, 0x48,
|
||||||
|
0xad, 0x11, 0x10, 0x85, 0x01, 0xa9, 0x00, 0x20,
|
||||||
|
0x15, 0x10, 0x68, 0x85, 0x01, 0xce, 0x19, 0xd0,
|
||||||
|
0xad, 0x0d, 0xdc, 0x68, 0xa8, 0x68, 0xaa, 0x68,
|
||||||
|
0x40, 0x02, 0x00, 0x00, 0x01, 0x82, 0x02, 0x82,
|
||||||
|
0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x0e, 0x82,
|
||||||
|
0x03, 0x82, 0x22, 0x82, 0x09, 0x82, 0x11, 0x82,
|
||||||
|
0x03, 0x82, 0x0f, 0x82, 0x05, 0x82, 0x05, 0x22,
|
||||||
|
0x05, 0x82, 0x0a, 0x82, 0x0d, 0x82, 0x09, 0x82,
|
||||||
|
0x04, 0x82, 0x04, 0x82, 0x03, 0x82, 0x05, 0x82,
|
||||||
|
0x0a, 0x82, 0x06, 0x82, 0x07, 0x82, 0x00, 0x00,
|
||||||
|
0x00, 0x00,
|
Binary file not shown.
|
@ -0,0 +1,10 @@
|
||||||
|
* Refine the MOS 6581 filter model / parameters. Build an accurate MOS
|
||||||
|
8580 filter model.
|
||||||
|
|
||||||
|
* Expose an interface for tunable filter parameters.
|
||||||
|
|
||||||
|
* Write documentation. Possibly a paper describing how SID was reverse
|
||||||
|
engineered.
|
||||||
|
|
||||||
|
* Implement a SID tune player. A PSID player, VSID, is partly
|
||||||
|
implemented in VICE.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
@mainpage libsidplayfp
|
||||||
|
|
||||||
|
A library to play Commodore 64 music derived from libsidplay2.<br/>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
Libsidplayfp (and its console frontend sidplayfp) is a fork of sidplay2
|
||||||
|
born with the aim to improve the quality of emulating the 6581, 8580 chips
|
||||||
|
and the surrounding C64 system in order to play SID music better.<br/>
|
||||||
|
|
||||||
|
Copyright (c) 2000-2001 Simon White<br/>
|
||||||
|
Copyright (c) 2007-2010 Antti Lankila<br/>
|
||||||
|
Copyright (c) 2010-2014 Leandro Nini <drfiemost@users.sourceforge.net><br/>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
STILView (or more precisely, the STIL class written in C++) is intended to be
|
||||||
|
compiled with the various SID emulators available on many platforms to provide
|
||||||
|
the capability of showing STIL and BUG information along with the given SID
|
||||||
|
that is currently being played in the emulator. It requires HVSC v2.6
|
||||||
|
(post-update #12) or later to function correctly, but it will work with
|
||||||
|
earlier versions to a limited extent.
|
||||||
|
|
||||||
|
Copyright (C) 1998, 2002 LaLa<br/>
|
||||||
|
Copyright (C) 2012-2013 Leandro Nini <drfiemost@users.sourceforge.net><br/>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
Home page:<br/>
|
||||||
|
http://sourceforge.net/projects/sidplay-residfp/
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify<br/>
|
||||||
|
it under the terms of the GNU General Public License as published by<br/>
|
||||||
|
the Free Software Foundation; either version 2 of the License, or<br/>
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,<br/>
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of<br/>
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br/>
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License<br/>
|
||||||
|
along with this program; if not, write to the Free Software<br/>
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
\example demo.cpp
|
||||||
|
*/
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,35 @@
|
||||||
|
|
||||||
|
AUTOMAKE_OPTIONS = foreign subdir-objects
|
||||||
|
|
||||||
|
if ENABLE_TEST
|
||||||
|
|
||||||
|
AM_CPPFLAGS = \
|
||||||
|
-I $(top_builddir)/src/builders/residfp-builder/residfp
|
||||||
|
|
||||||
|
TESTS = \
|
||||||
|
TestEnvelopeGenerator \
|
||||||
|
TestSpline \
|
||||||
|
TestDac
|
||||||
|
|
||||||
|
check_PROGRAMS = $(TESTS)
|
||||||
|
|
||||||
|
TestEnvelopeGenerator_SOURCES = \
|
||||||
|
Main.cpp \
|
||||||
|
TestEnvelopeGenerator.cpp
|
||||||
|
TestEnvelopeGenerator_LDADD = -lUnitTest++ \
|
||||||
|
$(top_builddir)/src/builders/residfp-builder/residfp/EnvelopeGenerator.o \
|
||||||
|
$(top_builddir)/src/builders/residfp-builder/residfp/Dac.o
|
||||||
|
|
||||||
|
TestSpline_SOURCES = \
|
||||||
|
Main.cpp \
|
||||||
|
TestSpline.cpp
|
||||||
|
TestSpline_LDADD = -lUnitTest++\
|
||||||
|
$(top_builddir)/src/builders/residfp-builder/residfp/Spline.o
|
||||||
|
|
||||||
|
TestDac_SOURCES = \
|
||||||
|
Main.cpp \
|
||||||
|
TestDac.cpp
|
||||||
|
TestDac_LDADD = -lUnitTest++\
|
||||||
|
$(top_builddir)/src/builders/residfp-builder/residfp/Dac.o
|
||||||
|
|
||||||
|
endif
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,109 @@
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// This file is part of reSID, a MOS6581 SID emulator engine.
|
||||||
|
// Copyright (C) 2010 Dag Lem <resid@nimrod.no>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef RESID_VOICE_H
|
||||||
|
#define RESID_VOICE_H
|
||||||
|
|
||||||
|
#include "resid-config.h"
|
||||||
|
#include "wave.h"
|
||||||
|
#include "envelope.h"
|
||||||
|
|
||||||
|
namespace reSID
|
||||||
|
{
|
||||||
|
|
||||||
|
class Voice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Voice();
|
||||||
|
|
||||||
|
void set_chip_model(chip_model model);
|
||||||
|
void set_sync_source(Voice*);
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
void writeCONTROL_REG(reg8);
|
||||||
|
|
||||||
|
// Amplitude modulated waveform output.
|
||||||
|
// Range [-2048*255, 2047*255].
|
||||||
|
int output();
|
||||||
|
|
||||||
|
WaveformGenerator wave;
|
||||||
|
EnvelopeGenerator envelope;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Waveform D/A zero level.
|
||||||
|
short wave_zero;
|
||||||
|
|
||||||
|
friend class SID;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Inline functions.
|
||||||
|
// The following function is defined inline because it is called every
|
||||||
|
// time a sample is calculated.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if RESID_INLINING || defined(RESID_VOICE_CC)
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Amplitude modulated waveform output (20 bits).
|
||||||
|
// Ideal range [-2048*255, 2047*255].
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// The output for a voice is produced by a multiplying DAC, where the
|
||||||
|
// waveform output modulates the envelope output.
|
||||||
|
//
|
||||||
|
// As noted by Bob Yannes: "The 8-bit output of the Envelope Generator was then
|
||||||
|
// sent to the Multiplying D/A converter to modulate the amplitude of the
|
||||||
|
// selected Oscillator Waveform (to be technically accurate, actually the
|
||||||
|
// waveform was modulating the output of the Envelope Generator, but the result
|
||||||
|
// is the same)".
|
||||||
|
//
|
||||||
|
// 7 6 5 4 3 2 1 0 VGND
|
||||||
|
// | | | | | | | | | Missing
|
||||||
|
// 2R 2R 2R 2R 2R 2R 2R 2R 2R termination
|
||||||
|
// | | | | | | | | |
|
||||||
|
// --R---R---R---R---R---R---R-- ---
|
||||||
|
// | _____
|
||||||
|
// __|__ __|__ |
|
||||||
|
// ----- ===== |
|
||||||
|
// | | | | |
|
||||||
|
// 12V --- ----- ------- GND
|
||||||
|
// |
|
||||||
|
// vout
|
||||||
|
//
|
||||||
|
// Bit on: wout (see figure in wave.h)
|
||||||
|
// Bit off: 5V (VGND)
|
||||||
|
//
|
||||||
|
// As is the case with all MOS 6581 DACs, the termination to (virtual) ground
|
||||||
|
// at bit 0 is missing. The MOS 8580 has correct termination.
|
||||||
|
//
|
||||||
|
|
||||||
|
RESID_INLINE
|
||||||
|
int Voice::output()
|
||||||
|
{
|
||||||
|
// Multiply oscillator output with envelope output.
|
||||||
|
return (wave.output() - wave_zero)*envelope.output();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // RESID_INLINING || defined(RESID_VOICE_CC)
|
||||||
|
|
||||||
|
} // namespace reSID
|
||||||
|
|
||||||
|
#endif // not RESID_VOICE_H
|
|
@ -0,0 +1,22 @@
|
||||||
|
## Process this file with automake to create Makefile.in
|
||||||
|
|
||||||
|
AR = @AR@
|
||||||
|
|
||||||
|
noinst_LIBRARIES = libresid.a
|
||||||
|
|
||||||
|
libresid_a_SOURCES = sid.cc voice.cc wave.cc envelope.cc filter.cc dac.cc extfilt.cc pot.cc version.cc
|
||||||
|
|
||||||
|
BUILT_SOURCES = $(noinst_DATA:.dat=.h)
|
||||||
|
|
||||||
|
noinst_HEADERS = sid.h voice.h wave.h envelope.h filter.h dac.h extfilt.h pot.h spline.h resid-config.h $(noinst_DATA:.dat=.h)
|
||||||
|
|
||||||
|
noinst_DATA = wave6581_PST.dat wave6581_PS_.dat wave6581_P_T.dat wave6581__ST.dat wave8580_PST.dat wave8580_PS_.dat wave8580_P_T.dat wave8580__ST.dat
|
||||||
|
|
||||||
|
noinst_SCRIPTS = samp2src.pl
|
||||||
|
|
||||||
|
EXTRA_DIST = $(noinst_HEADERS) $(noinst_DATA) $(noinst_SCRIPTS) README.VICE
|
||||||
|
|
||||||
|
SUFFIXES = .dat
|
||||||
|
|
||||||
|
.dat.h:
|
||||||
|
$(PERL) $(srcdir)/samp2src.pl $* $< $(srcdir)/$@
|
Binary file not shown.
|
@ -0,0 +1,131 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2011-2014 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
* Copyright 2007-2010 Antti Lankila
|
||||||
|
* Copyright 2001 Simon White
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef C64CIA_H
|
||||||
|
#define C64CIA_H
|
||||||
|
|
||||||
|
// The CIA emulations are very generic and here we need to effectively
|
||||||
|
// wire them into the computer (like adding a chip to a PCB).
|
||||||
|
|
||||||
|
#include "Banks/Bank.h"
|
||||||
|
#include "c64/c64env.h"
|
||||||
|
#include "sidendian.h"
|
||||||
|
#include "CIA/mos6526.h"
|
||||||
|
|
||||||
|
#include "sidcxx11.h"
|
||||||
|
|
||||||
|
namespace libsidplayfp
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CIA 1
|
||||||
|
*
|
||||||
|
* Generates IRQs
|
||||||
|
*
|
||||||
|
* Located at $DC00-$DCFF
|
||||||
|
*/
|
||||||
|
class c64cia1: public MOS6526, public Bank
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
c64env &m_env;
|
||||||
|
uint_least16_t last_ta;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void interrupt(bool state) override
|
||||||
|
{
|
||||||
|
m_env.interruptIRQ(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void portB() override
|
||||||
|
{
|
||||||
|
m_env.lightpen((prb | ~ddrb) & 0x10);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
c64cia1(c64env *env) :
|
||||||
|
MOS6526(&(env->context())),
|
||||||
|
m_env(*env) {}
|
||||||
|
|
||||||
|
void poke(uint_least16_t address, uint8_t value) override
|
||||||
|
{
|
||||||
|
write(endian_16lo8(address), value);
|
||||||
|
|
||||||
|
// Save the value written to Timer A
|
||||||
|
if (address == 0xDC04 || address == 0xDC05)
|
||||||
|
{
|
||||||
|
if (timerA.getTimer() != 0)
|
||||||
|
last_ta = timerA.getTimer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t peek(uint_least16_t address) override
|
||||||
|
{
|
||||||
|
return read(endian_16lo8(address));
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() override
|
||||||
|
{
|
||||||
|
last_ta = 0;
|
||||||
|
MOS6526::reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint_least16_t getTimerA() const { return last_ta; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CIA 2
|
||||||
|
*
|
||||||
|
* Generates NMIs
|
||||||
|
*
|
||||||
|
* Located at $DD00-$DDFF
|
||||||
|
*/
|
||||||
|
class c64cia2: public MOS6526, public Bank
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
c64env &m_env;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void interrupt(bool state) override
|
||||||
|
{
|
||||||
|
if (state)
|
||||||
|
m_env.interruptNMI();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
c64cia2(c64env *env) :
|
||||||
|
MOS6526(&(env->context())),
|
||||||
|
m_env(*env) {}
|
||||||
|
|
||||||
|
void poke(uint_least16_t address, uint8_t value) override
|
||||||
|
{
|
||||||
|
write(address, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t peek(uint_least16_t address) override
|
||||||
|
{
|
||||||
|
return read(address);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // C64CIA_H
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
link trurl6581r3_4885.ini
|
Binary file not shown.
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2011-2014 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
* Copyright 2007-2010 Antti Lankila
|
||||||
|
* Copyright 2004,2010 Dag Lem
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OPAMP_H
|
||||||
|
#define OPAMP_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include "Spline.h"
|
||||||
|
|
||||||
|
namespace reSIDfp
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find output voltage in inverting gain and inverting summer SID op-amp
|
||||||
|
* circuits, using a combination of Newton-Raphson and bisection.
|
||||||
|
*
|
||||||
|
* ---R2--
|
||||||
|
* | |
|
||||||
|
* vi ---R1-----[A>----- vo
|
||||||
|
* vx
|
||||||
|
*
|
||||||
|
* From Kirchoff's current law it follows that
|
||||||
|
*
|
||||||
|
* IR1f + IR2r = 0
|
||||||
|
*
|
||||||
|
* Substituting the triode mode transistor model K*W/L*(Vgst^2 - Vgdt^2)
|
||||||
|
* for the currents, we get:
|
||||||
|
*
|
||||||
|
* n*((Vddt - vx)^2 - (Vddt - vi)^2) + (Vddt - vx)^2 - (Vddt - vo)^2 = 0
|
||||||
|
*
|
||||||
|
* Our root function f can thus be written as:
|
||||||
|
*
|
||||||
|
* f = (n + 1)*(Vddt - vx)^2 - n*(Vddt - vi)^2 - (Vddt - vo)^2 = 0
|
||||||
|
*
|
||||||
|
* Using substitution constants
|
||||||
|
*
|
||||||
|
* a = n + 1
|
||||||
|
* b = Vddt
|
||||||
|
* c = n*(Vddt - vi)^2
|
||||||
|
*
|
||||||
|
* the equations for the root function and its derivative can be written as:
|
||||||
|
*
|
||||||
|
* f = a*(b - vx)^2 - c - (b - vo)^2
|
||||||
|
* df = 2*((b - vo)*dvo - a*(b - vx))
|
||||||
|
*/
|
||||||
|
class OpAmp
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/// Current root position (cached as guess to speed up next iteration)
|
||||||
|
double x;
|
||||||
|
|
||||||
|
const double kVddt, vmin, vmax;
|
||||||
|
|
||||||
|
std::auto_ptr<Spline> const opamp;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Opamp input -> output voltage conversion
|
||||||
|
*
|
||||||
|
* @param opamp opamp mapping table as pairs of points (in -> out)
|
||||||
|
* @param opamplength length of the opamp array
|
||||||
|
* @param kVddt transistor dt parameter (in volts)
|
||||||
|
*/
|
||||||
|
OpAmp(const Spline::Point opamp[], int opamplength, double kVddt) :
|
||||||
|
x(0.),
|
||||||
|
kVddt(kVddt),
|
||||||
|
vmin(opamp[0].x),
|
||||||
|
vmax(opamp[opamplength - 1].x),
|
||||||
|
opamp(new Spline(opamp, opamplength)) {}
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
x = vmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Solve the opamp equation for input vi in loading context n
|
||||||
|
*
|
||||||
|
* @param n the ratio of input/output loading
|
||||||
|
* @param vi input
|
||||||
|
* @return vo
|
||||||
|
*/
|
||||||
|
double solve(double n, double vi);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace reSIDfp
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2011-2013 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
* Copyright 2007-2010 Antti Lankila
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RESAMPLER_H
|
||||||
|
#define RESAMPLER_H
|
||||||
|
|
||||||
|
namespace reSIDfp
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstraction of a resampling process. Given enough input, produces output.
|
||||||
|
* Constructors take additional arguments that configure these objects.
|
||||||
|
*/
|
||||||
|
class Resampler
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
virtual int output() const = 0;
|
||||||
|
|
||||||
|
Resampler() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~Resampler() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Input a sample into resampler. Output "true" when resampler is ready with new sample.
|
||||||
|
*
|
||||||
|
* @param sample input sample
|
||||||
|
* @return true when a sample is ready
|
||||||
|
*/
|
||||||
|
virtual bool input(int sample) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output a sample from resampler.
|
||||||
|
*
|
||||||
|
* @return resampled sample
|
||||||
|
*/
|
||||||
|
short getOutput() const
|
||||||
|
{
|
||||||
|
int value = output();
|
||||||
|
|
||||||
|
// Clip signed integer value into the -32768,32767 range.
|
||||||
|
if (value < -32768) value = -32768;
|
||||||
|
if (value > 32767) value = 32767;
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void reset() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace reSIDfp
|
||||||
|
|
||||||
|
#endif
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,83 @@
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// This file is part of reSID, a MOS6581 SID emulator engine.
|
||||||
|
// Copyright (C) 2010 Dag Lem <resid@nimrod.no>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef RESID_SIDDEFS_H
|
||||||
|
#define RESID_SIDDEFS_H
|
||||||
|
|
||||||
|
// Compilation configuration.
|
||||||
|
#define RESID_INLINING @RESID_INLINING@
|
||||||
|
#define RESID_INLINE @RESID_INLINE@
|
||||||
|
#define RESID_BRANCH_HINTS @RESID_BRANCH_HINTS@
|
||||||
|
|
||||||
|
// Compiler specifics.
|
||||||
|
#define HAVE_BOOL @RESID_HAVE_BOOL@
|
||||||
|
#define HAVE_BUILTIN_EXPECT @HAVE_BUILTIN_EXPECT@
|
||||||
|
|
||||||
|
// Define bool, true, and false for C++ compilers that lack these keywords.
|
||||||
|
#if !HAVE_BOOL
|
||||||
|
typedef int bool;
|
||||||
|
const bool true = 1;
|
||||||
|
const bool false = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Branch prediction macros, lifted off the Linux kernel.
|
||||||
|
#if RESID_BRANCH_HINTS && HAVE_BUILTIN_EXPECT
|
||||||
|
#define likely(x) __builtin_expect(!!(x), 1)
|
||||||
|
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
|
#else
|
||||||
|
#define likely(x) (x)
|
||||||
|
#define unlikely(x) (x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace reSID {
|
||||||
|
|
||||||
|
// We could have used the smallest possible data type for each SID register,
|
||||||
|
// however this would give a slower engine because of data type conversions.
|
||||||
|
// An int is assumed to be at least 32 bits (necessary in the types reg24
|
||||||
|
// and cycle_count). GNU does not support 16-bit machines
|
||||||
|
// (GNU Coding Standards: Portability between CPUs), so this should be
|
||||||
|
// a valid assumption.
|
||||||
|
|
||||||
|
typedef unsigned int reg4;
|
||||||
|
typedef unsigned int reg8;
|
||||||
|
typedef unsigned int reg12;
|
||||||
|
typedef unsigned int reg16;
|
||||||
|
typedef unsigned int reg24;
|
||||||
|
|
||||||
|
typedef int cycle_count;
|
||||||
|
typedef short short_point[2];
|
||||||
|
typedef double double_point[2];
|
||||||
|
|
||||||
|
enum chip_model { MOS6581, MOS8580 };
|
||||||
|
|
||||||
|
enum sampling_method { SAMPLE_FAST, SAMPLE_INTERPOLATE,
|
||||||
|
SAMPLE_RESAMPLE, SAMPLE_RESAMPLE_FASTMEM };
|
||||||
|
|
||||||
|
} // namespace reSID
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#ifndef RESID_VERSION_CC
|
||||||
|
extern const char* resid_version_string;
|
||||||
|
#else
|
||||||
|
const char* resid_version_string = "1.0-pre2";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // not RESID_SIDDEFS_H
|
|
@ -0,0 +1,9 @@
|
||||||
|
[Filter]
|
||||||
|
DistortionAttenuation=0.50
|
||||||
|
DistortionNonlinearity=3.3e6
|
||||||
|
VoiceNonlinearity =1.80
|
||||||
|
Type3BaseResistance =1.1e6
|
||||||
|
Type3Offset =8e6
|
||||||
|
Type3Steepness =1.0052
|
||||||
|
Type3MinimumFETResistance=1.7e4
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2014 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MD5_FACTORY_H
|
||||||
|
#define MD5_FACTORY_H
|
||||||
|
|
||||||
|
#include "iMd5.h"
|
||||||
|
|
||||||
|
#include "sidcxx11.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBGCRYPT
|
||||||
|
# include "md5Gcrypt.h"
|
||||||
|
#else
|
||||||
|
# include "md5Internal.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace libsidplayfp
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace md5Factory
|
||||||
|
{
|
||||||
|
static std::unique_ptr<iMd5> get()
|
||||||
|
{
|
||||||
|
return std::unique_ptr<iMd5>(
|
||||||
|
#ifdef HAVE_LIBGCRYPT
|
||||||
|
new md5Gcrypt()
|
||||||
|
#else
|
||||||
|
new md5Internal()
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // MD5_FACTORY_H
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* This file is part of sidplayfp, a console SID player.
|
||||||
|
*
|
||||||
|
* Copyright 2014 Leandro Nini
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TYPES_H
|
||||||
|
#define TYPES_H
|
||||||
|
|
||||||
|
#include "sidfstream.h"
|
||||||
|
|
||||||
|
# define SID_WIFSTREAM sid_wifstream
|
||||||
|
# define SID_WOFSTREAM sid_wofstream
|
||||||
|
# define SID_IFSTREAM sid_ifstream
|
||||||
|
# define SID_OFSTREAM sid_ofstream
|
||||||
|
|
||||||
|
#if defined(_WIN32) && defined(UNICODE)
|
||||||
|
# define SID_STRING std::wstring
|
||||||
|
# define SID_STRINGTREAM std::wstringstream
|
||||||
|
# define SID_COUT std::wcout
|
||||||
|
#else
|
||||||
|
# define SID_STRING std::string
|
||||||
|
# define SID_STRINGTREAM std::stringstream
|
||||||
|
# define SID_COUT std::cout
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
# define TCHAR char
|
||||||
|
# define TEXT(x) x
|
||||||
|
# define SEPARATOR "/"
|
||||||
|
#else
|
||||||
|
# include <windows.h>
|
||||||
|
# define SEPARATOR TEXT("\\")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,36 @@
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// This file is part of reSID, a MOS6581 SID emulator engine.
|
||||||
|
// Copyright (C) 2010 Dag Lem <resid@nimrod.no>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef RESID_POT_H
|
||||||
|
#define RESID_POT_H
|
||||||
|
|
||||||
|
#include "resid-config.h"
|
||||||
|
|
||||||
|
namespace reSID
|
||||||
|
{
|
||||||
|
|
||||||
|
class Potentiometer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
reg8 readPOT();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace reSID
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2011-2014 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
* Copyright 2007-2010 Antti Lankila
|
||||||
|
* Copyright 2001 Simon White
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RESIDFP_EMU_H
|
||||||
|
#define RESIDFP_EMU_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "residfp/SID.h"
|
||||||
|
#include "sidplayfp/SidConfig.h"
|
||||||
|
#include "sidemu.h"
|
||||||
|
#include "sidplayfp/event.h"
|
||||||
|
|
||||||
|
#include "sidcxx11.h"
|
||||||
|
|
||||||
|
class sidbuilder;
|
||||||
|
|
||||||
|
#define RESID_NAMESPACE reSIDfp
|
||||||
|
|
||||||
|
class ReSIDfp: public sidemu
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
RESID_NAMESPACE::SID &m_sid;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const char* getCredits();
|
||||||
|
|
||||||
|
public:
|
||||||
|
ReSIDfp(sidbuilder *builder);
|
||||||
|
~ReSIDfp();
|
||||||
|
|
||||||
|
bool getStatus() const { return m_status; }
|
||||||
|
|
||||||
|
// Standard component functions
|
||||||
|
void reset() override { sidemu::reset(); }
|
||||||
|
|
||||||
|
uint8_t read(uint_least8_t addr) override;
|
||||||
|
void write(uint_least8_t addr, uint8_t data) override;
|
||||||
|
|
||||||
|
// c64sid functions
|
||||||
|
void reset(uint8_t volume) override;
|
||||||
|
|
||||||
|
// Standard SID emu functions
|
||||||
|
void clock() override;
|
||||||
|
|
||||||
|
void sampling(float systemclock, float freq,
|
||||||
|
SidConfig::sampling_method_t method, bool) override;
|
||||||
|
|
||||||
|
void voice(unsigned int num, bool mute) override { m_sid.mute(num, mute); }
|
||||||
|
|
||||||
|
void model(SidConfig::sid_model_t model) override;
|
||||||
|
|
||||||
|
// Specific to resid
|
||||||
|
void filter(bool enable);
|
||||||
|
void filter6581Curve(double filterCurve);
|
||||||
|
void filter8580Curve(double filterCurve);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RESIDFP_EMU_H
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2011-2013 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
* Copyright 2007-2010 Antti Lankila
|
||||||
|
* Copyright 2000 Simon White
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mmu.h"
|
||||||
|
|
||||||
|
namespace libsidplayfp
|
||||||
|
{
|
||||||
|
|
||||||
|
class Bank;
|
||||||
|
|
||||||
|
MMU::MMU(EventContext *context, Bank* ioBank) :
|
||||||
|
context(*context),
|
||||||
|
loram(false),
|
||||||
|
hiram(false),
|
||||||
|
charen(false),
|
||||||
|
ioBank(ioBank),
|
||||||
|
zeroRAMBank(this, &ramBank)
|
||||||
|
{
|
||||||
|
cpuReadMap[0] = &zeroRAMBank;
|
||||||
|
cpuWriteMap[0] = &zeroRAMBank;
|
||||||
|
|
||||||
|
for (int i = 1; i < 16; i++)
|
||||||
|
{
|
||||||
|
cpuReadMap[i] = &ramBank;
|
||||||
|
cpuWriteMap[i] = &ramBank;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMU::setCpuPort(int state)
|
||||||
|
{
|
||||||
|
loram = (state & 1) != 0;
|
||||||
|
hiram = (state & 2) != 0;
|
||||||
|
charen = (state & 4) != 0;
|
||||||
|
updateMappingPHI2();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMU::updateMappingPHI2()
|
||||||
|
{
|
||||||
|
cpuReadMap[0xe] = cpuReadMap[0xf] = hiram ? (Bank*)&kernalRomBank : &ramBank;
|
||||||
|
cpuReadMap[0xa] = cpuReadMap[0xb] = (loram && hiram) ? (Bank*)&basicRomBank : &ramBank;
|
||||||
|
|
||||||
|
if (charen && (loram || hiram))
|
||||||
|
{
|
||||||
|
cpuReadMap[0xd] = cpuWriteMap[0xd] = ioBank;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cpuReadMap[0xd] = (!charen && (loram || hiram)) ? (Bank*)&characterRomBank : &ramBank;
|
||||||
|
cpuWriteMap[0xd] = &ramBank;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMU::reset()
|
||||||
|
{
|
||||||
|
ramBank.reset();
|
||||||
|
zeroRAMBank.reset();
|
||||||
|
|
||||||
|
// Reset the ROMs to undo the hacks applied
|
||||||
|
kernalRomBank.reset();
|
||||||
|
basicRomBank.reset();
|
||||||
|
|
||||||
|
updateMappingPHI2();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,257 @@
|
||||||
|
# MOS 8580R5 1489 25 HONG KONG HH112217 HC-30
|
||||||
|
0 0
|
||||||
|
8 0
|
||||||
|
16 0
|
||||||
|
24 140
|
||||||
|
32 190
|
||||||
|
40 235
|
||||||
|
48 284
|
||||||
|
56 335
|
||||||
|
64 395
|
||||||
|
72 442
|
||||||
|
80 478
|
||||||
|
88 526
|
||||||
|
96 578
|
||||||
|
104 626
|
||||||
|
112 665
|
||||||
|
120 710
|
||||||
|
128 759
|
||||||
|
136 815
|
||||||
|
144 852
|
||||||
|
152 917
|
||||||
|
160 963
|
||||||
|
168 1003
|
||||||
|
176 1051
|
||||||
|
184 1080
|
||||||
|
192 1143
|
||||||
|
200 1200
|
||||||
|
208 1260
|
||||||
|
216 1297
|
||||||
|
224 1343
|
||||||
|
232 1354
|
||||||
|
240 1419
|
||||||
|
248 1494
|
||||||
|
256 1583
|
||||||
|
264 1592
|
||||||
|
272 1651
|
||||||
|
280 1666
|
||||||
|
288 1736
|
||||||
|
296 1786
|
||||||
|
304 1841
|
||||||
|
312 1892
|
||||||
|
320 1921
|
||||||
|
328 1993
|
||||||
|
336 2016
|
||||||
|
344 2048
|
||||||
|
352 2099
|
||||||
|
360 2140
|
||||||
|
368 2214
|
||||||
|
376 2248
|
||||||
|
384 2321
|
||||||
|
392 2356
|
||||||
|
400 2382
|
||||||
|
408 2471
|
||||||
|
416 2497
|
||||||
|
424 2520
|
||||||
|
432 2556
|
||||||
|
440 2636
|
||||||
|
448 2696
|
||||||
|
456 2711
|
||||||
|
464 2776
|
||||||
|
472 2824
|
||||||
|
480 2891
|
||||||
|
488 2899
|
||||||
|
496 2952
|
||||||
|
504 2969
|
||||||
|
512 3039
|
||||||
|
520 3115
|
||||||
|
528 3169
|
||||||
|
536 3188
|
||||||
|
544 3242
|
||||||
|
552 3307
|
||||||
|
560 3330
|
||||||
|
568 3394
|
||||||
|
576 3440
|
||||||
|
584 3470
|
||||||
|
592 3483
|
||||||
|
600 3543
|
||||||
|
608 3571
|
||||||
|
616 3658
|
||||||
|
624 3697
|
||||||
|
632 3730
|
||||||
|
640 3763
|
||||||
|
648 3850
|
||||||
|
656 3833
|
||||||
|
664 3960
|
||||||
|
672 3983
|
||||||
|
680 3987
|
||||||
|
688 4065
|
||||||
|
696 4091
|
||||||
|
704 4162
|
||||||
|
712 4144
|
||||||
|
720 4207
|
||||||
|
728 4257
|
||||||
|
736 4347
|
||||||
|
744 4320
|
||||||
|
752 4377
|
||||||
|
760 4429
|
||||||
|
768 4490
|
||||||
|
776 4556
|
||||||
|
784 4558
|
||||||
|
792 4711
|
||||||
|
800 4683
|
||||||
|
808 4722
|
||||||
|
816 4768
|
||||||
|
824 4851
|
||||||
|
832 4884
|
||||||
|
840 4987
|
||||||
|
848 5037
|
||||||
|
856 5079
|
||||||
|
864 5114
|
||||||
|
872 5173
|
||||||
|
880 5166
|
||||||
|
888 5228
|
||||||
|
896 5359
|
||||||
|
904 5352
|
||||||
|
912 5332
|
||||||
|
920 5418
|
||||||
|
928 5415
|
||||||
|
936 5514
|
||||||
|
944 5487
|
||||||
|
952 5557
|
||||||
|
960 5668
|
||||||
|
968 5618
|
||||||
|
976 5658
|
||||||
|
984 5738
|
||||||
|
992 5759
|
||||||
|
1000 5850
|
||||||
|
1008 5828
|
||||||
|
1016 5859
|
||||||
|
1024 5905
|
||||||
|
1032 6027
|
||||||
|
1040 5994
|
||||||
|
1048 5983
|
||||||
|
1056 6172
|
||||||
|
1064 6122
|
||||||
|
1072 6153
|
||||||
|
1080 6220
|
||||||
|
1088 6270
|
||||||
|
1096 6334
|
||||||
|
1104 6369
|
||||||
|
1112 6441
|
||||||
|
1120 6431
|
||||||
|
1128 6566
|
||||||
|
1136 6569
|
||||||
|
1144 6612
|
||||||
|
1152 6664
|
||||||
|
1160 6723
|
||||||
|
1168 6800
|
||||||
|
1176 6775
|
||||||
|
1184 6829
|
||||||
|
1192 6893
|
||||||
|
1200 6934
|
||||||
|
1208 6918
|
||||||
|
1216 6962
|
||||||
|
1224 7123
|
||||||
|
1232 7079
|
||||||
|
1240 7144
|
||||||
|
1248 7185
|
||||||
|
1256 7315
|
||||||
|
1264 7304
|
||||||
|
1272 7344
|
||||||
|
1280 7402
|
||||||
|
1288 7409
|
||||||
|
1296 7431
|
||||||
|
1304 7512
|
||||||
|
1312 7562
|
||||||
|
1320 7562
|
||||||
|
1328 7662
|
||||||
|
1336 7657
|
||||||
|
1344 7719
|
||||||
|
1352 7779
|
||||||
|
1360 7773
|
||||||
|
1368 7829
|
||||||
|
1376 7857
|
||||||
|
1384 7933
|
||||||
|
1392 7983
|
||||||
|
1400 7977
|
||||||
|
1408 8025
|
||||||
|
1416 8079
|
||||||
|
1424 8142
|
||||||
|
1432 8210
|
||||||
|
1440 8175
|
||||||
|
1448 8258
|
||||||
|
1456 8284
|
||||||
|
1464 8405
|
||||||
|
1472 8382
|
||||||
|
1480 8402
|
||||||
|
1488 8406
|
||||||
|
1496 8496
|
||||||
|
1504 8537
|
||||||
|
1512 8589
|
||||||
|
1520 8580
|
||||||
|
1528 8630
|
||||||
|
1536 8713
|
||||||
|
1544 8728
|
||||||
|
1552 8810
|
||||||
|
1560 8765
|
||||||
|
1568 8806
|
||||||
|
1576 8920
|
||||||
|
1584 8922
|
||||||
|
1592 8959
|
||||||
|
1600 9017
|
||||||
|
1608 9106
|
||||||
|
1616 9092
|
||||||
|
1624 9187
|
||||||
|
1632 9199
|
||||||
|
1640 9230
|
||||||
|
1648 9199
|
||||||
|
1656 9280
|
||||||
|
1664 9389
|
||||||
|
1672 9329
|
||||||
|
1680 9423
|
||||||
|
1688 9466
|
||||||
|
1696 9486
|
||||||
|
1704 9588
|
||||||
|
1712 9578
|
||||||
|
1720 9605
|
||||||
|
1728 9683
|
||||||
|
1736 9696
|
||||||
|
1744 9766
|
||||||
|
1752 9860
|
||||||
|
1760 9883
|
||||||
|
1768 9994
|
||||||
|
1776 9958
|
||||||
|
1784 10074
|
||||||
|
1792 10075
|
||||||
|
1800 10068
|
||||||
|
1808 10283
|
||||||
|
1816 10286
|
||||||
|
1824 10287
|
||||||
|
1832 10384
|
||||||
|
1840 10348
|
||||||
|
1848 10541
|
||||||
|
1856 10484
|
||||||
|
1864 10582
|
||||||
|
1872 10475
|
||||||
|
1880 10521
|
||||||
|
1888 10609
|
||||||
|
1896 10667
|
||||||
|
1904 10685
|
||||||
|
1912 10699
|
||||||
|
1920 10769
|
||||||
|
1928 10806
|
||||||
|
1936 10859
|
||||||
|
1944 10842
|
||||||
|
1952 10912
|
||||||
|
1960 10956
|
||||||
|
1968 11060
|
||||||
|
1976 11065
|
||||||
|
1984 11120
|
||||||
|
1992 11083
|
||||||
|
2000 11191
|
||||||
|
2008 11187
|
||||||
|
2016 11182
|
||||||
|
2024 11251
|
||||||
|
2032 11285
|
||||||
|
2040 11325
|
|
@ -0,0 +1 @@
|
||||||
|
link zrx6581r3_1984.ini
|
|
@ -0,0 +1,9 @@
|
||||||
|
[Filter]
|
||||||
|
DistortionAttenuation=0.50
|
||||||
|
DistortionNonlinearity=3.3e6
|
||||||
|
VoiceNonlinearity =1.80
|
||||||
|
Type3BaseResistance=1522171.922983084
|
||||||
|
Type3Offset=21729926.667291082
|
||||||
|
Type3Steepness=1.004994802537475
|
||||||
|
Type3MinimumFETResistance=14299.149638099827
|
||||||
|
|
|
@ -0,0 +1,400 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2012-2014 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
* Copyright 2007-2010 Antti Lankila
|
||||||
|
* Copyright 2000-2001 Simon White
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PSID.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "sidplayfp/SidTuneInfo.h"
|
||||||
|
|
||||||
|
#include "sidendian.h"
|
||||||
|
#include "sidmd5.h"
|
||||||
|
|
||||||
|
#include "sidcxx11.h"
|
||||||
|
|
||||||
|
namespace libsidplayfp
|
||||||
|
{
|
||||||
|
|
||||||
|
#define PSID_MAXSTRLEN 32
|
||||||
|
|
||||||
|
|
||||||
|
// Header has been extended for 'RSID' format
|
||||||
|
// The following changes are present:
|
||||||
|
// id = 'RSID'
|
||||||
|
// version = 2 and 3 only
|
||||||
|
// play, load and speed reserved 0
|
||||||
|
// psidspecific flag is called C64BASIC flag
|
||||||
|
// init cannot be under ROMS/IO memory area
|
||||||
|
// load address cannot be less than $07E8
|
||||||
|
// info strings may be 32 characters long without trailing zero
|
||||||
|
|
||||||
|
struct psidHeader // all values are big-endian
|
||||||
|
{
|
||||||
|
uint32_t id; // 'PSID' or 'RSID' (ASCII)
|
||||||
|
uint16_t version; // 1, 2 or 3 only
|
||||||
|
uint16_t data; // 16-bit offset to binary data in file
|
||||||
|
uint16_t load; // 16-bit C64 address to load file to
|
||||||
|
uint16_t init; // 16-bit C64 address of init subroutine
|
||||||
|
uint16_t play; // 16-bit C64 address of play subroutine
|
||||||
|
uint16_t songs; // number of songs
|
||||||
|
uint16_t start; // start song out of [1..256]
|
||||||
|
uint32_t speed; // 32-bit speed info
|
||||||
|
// bit: 0=50 Hz, 1=CIA 1 Timer A (default: 60 Hz)
|
||||||
|
char name[PSID_MAXSTRLEN]; // ASCII strings, 31 characters long and
|
||||||
|
char author[PSID_MAXSTRLEN]; // terminated by a trailing zero
|
||||||
|
char released[PSID_MAXSTRLEN]; //
|
||||||
|
|
||||||
|
uint16_t flags; // only version >= 2
|
||||||
|
uint8_t relocStartPage; // only version >= 2ng
|
||||||
|
uint8_t relocPages; // only version >= 2ng
|
||||||
|
uint8_t sidChipBase2; // only version >= 3
|
||||||
|
uint8_t reserved; // only version >= 2
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PSID_MUS = 1 << 0,
|
||||||
|
PSID_SPECIFIC = 1 << 1, // These two are mutally exclusive
|
||||||
|
PSID_BASIC = 1 << 1,
|
||||||
|
PSID_CLOCK = 3 << 2,
|
||||||
|
PSID_SIDMODEL = 3 << 4
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PSID_CLOCK_UNKNOWN = 0,
|
||||||
|
PSID_CLOCK_PAL = 1 << 2,
|
||||||
|
PSID_CLOCK_NTSC = 1 << 3,
|
||||||
|
PSID_CLOCK_ANY = PSID_CLOCK_PAL | PSID_CLOCK_NTSC
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PSID_SIDMODEL1_UNKNOWN = 0,
|
||||||
|
PSID_SIDMODEL1_6581 = 1 << 4,
|
||||||
|
PSID_SIDMODEL1_8580 = 1 << 5,
|
||||||
|
PSID_SIDMODEL1_ANY = PSID_SIDMODEL1_6581 | PSID_SIDMODEL1_8580
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PSID_SIDMODEL2_UNKNOWN = 0,
|
||||||
|
PSID_SIDMODEL2_6581 = 1 << 6,
|
||||||
|
PSID_SIDMODEL2_8580 = 1 << 7,
|
||||||
|
PSID_SIDMODEL2_ANY = PSID_SIDMODEL2_6581 | PSID_SIDMODEL2_8580
|
||||||
|
};
|
||||||
|
|
||||||
|
// Format strings
|
||||||
|
const char TXT_FORMAT_PSID[] = "PlaySID one-file format (PSID)";
|
||||||
|
const char TXT_FORMAT_RSID[] = "Real C64 one-file format (RSID)";
|
||||||
|
const char TXT_UNKNOWN_PSID[] = "Unsupported PSID version";
|
||||||
|
const char TXT_UNKNOWN_RSID[] = "Unsupported RSID version";
|
||||||
|
|
||||||
|
const int psid_headerSize = 118;
|
||||||
|
const int psidv2_headerSize = psid_headerSize + 6;
|
||||||
|
|
||||||
|
// Magic fields
|
||||||
|
const uint32_t PSID_ID = 0x50534944;
|
||||||
|
const uint32_t RSID_ID = 0x52534944;
|
||||||
|
|
||||||
|
SidTuneBase* PSID::load(buffer_t& dataBuf)
|
||||||
|
{
|
||||||
|
// File format check
|
||||||
|
if (dataBuf.size() < 4
|
||||||
|
|| ((endian_big32(&dataBuf[0]) != PSID_ID)
|
||||||
|
&& (endian_big32(&dataBuf[0]) != RSID_ID)))
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
psidHeader pHeader;
|
||||||
|
readHeader(dataBuf, pHeader);
|
||||||
|
|
||||||
|
std::unique_ptr<PSID> tune(new PSID());
|
||||||
|
tune->tryLoad(pHeader);
|
||||||
|
|
||||||
|
return tune.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PSID::readHeader(const buffer_t &dataBuf, psidHeader &hdr)
|
||||||
|
{
|
||||||
|
// Due to security concerns, input must be at least as long as version 1
|
||||||
|
// header plus 16-bit C64 load address. That is the area which will be
|
||||||
|
// accessed.
|
||||||
|
if (dataBuf.size() < (psid_headerSize + 2))
|
||||||
|
{
|
||||||
|
throw loadError(ERR_TRUNCATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read v1 fields
|
||||||
|
hdr.id = endian_big32(&dataBuf[0]);
|
||||||
|
hdr.version = endian_big16(&dataBuf[4]);
|
||||||
|
hdr.data = endian_big16(&dataBuf[6]);
|
||||||
|
hdr.load = endian_big16(&dataBuf[8]);
|
||||||
|
hdr.init = endian_big16(&dataBuf[10]);
|
||||||
|
hdr.play = endian_big16(&dataBuf[12]);
|
||||||
|
hdr.songs = endian_big16(&dataBuf[14]);
|
||||||
|
hdr.start = endian_big16(&dataBuf[16]);
|
||||||
|
hdr.speed = endian_big32(&dataBuf[18]);
|
||||||
|
memcpy(hdr.name, &dataBuf[22], PSID_MAXSTRLEN);
|
||||||
|
memcpy(hdr.author, &dataBuf[54], PSID_MAXSTRLEN);
|
||||||
|
memcpy(hdr.released, &dataBuf[86], PSID_MAXSTRLEN);
|
||||||
|
|
||||||
|
if (hdr.version >= 2)
|
||||||
|
{
|
||||||
|
if (dataBuf.size() < (psidv2_headerSize + 2))
|
||||||
|
{
|
||||||
|
throw loadError(ERR_TRUNCATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read v2/3 fields
|
||||||
|
hdr.flags = endian_big16(&dataBuf[118]);
|
||||||
|
hdr.relocStartPage = dataBuf[120];
|
||||||
|
hdr.relocPages = dataBuf[121];
|
||||||
|
hdr.sidChipBase2 = dataBuf[122];
|
||||||
|
hdr.reserved = dataBuf[123];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PSID::tryLoad(const psidHeader &pHeader)
|
||||||
|
{
|
||||||
|
SidTuneInfo::compatibility_t compatibility = SidTuneInfo::COMPATIBILITY_C64;
|
||||||
|
|
||||||
|
// Require a valid ID and version number.
|
||||||
|
if (pHeader.id == PSID_ID)
|
||||||
|
{
|
||||||
|
switch (pHeader.version)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
compatibility = SidTuneInfo::COMPATIBILITY_PSID;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw loadError(TXT_UNKNOWN_PSID);
|
||||||
|
}
|
||||||
|
info->m_formatString = TXT_FORMAT_PSID;
|
||||||
|
}
|
||||||
|
else if (pHeader.id == RSID_ID)
|
||||||
|
{
|
||||||
|
switch (pHeader.version)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw loadError(TXT_UNKNOWN_RSID);
|
||||||
|
}
|
||||||
|
info->m_formatString = TXT_FORMAT_RSID;
|
||||||
|
compatibility = SidTuneInfo::COMPATIBILITY_R64;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileOffset = pHeader.data;
|
||||||
|
info->m_loadAddr = pHeader.load;
|
||||||
|
info->m_initAddr = pHeader.init;
|
||||||
|
info->m_playAddr = pHeader.play;
|
||||||
|
info->m_songs = pHeader.songs;
|
||||||
|
info->m_startSong = pHeader.start;
|
||||||
|
info->m_sidChipBase1 = 0xd400;
|
||||||
|
info->m_sidChipBase2 = 0;
|
||||||
|
info->m_compatibility = compatibility;
|
||||||
|
info->m_sidModel1 = SidTuneInfo::SIDMODEL_UNKNOWN;
|
||||||
|
info->m_sidModel2 = SidTuneInfo::SIDMODEL_UNKNOWN;
|
||||||
|
info->m_relocPages = 0;
|
||||||
|
info->m_relocStartPage = 0;
|
||||||
|
|
||||||
|
uint_least32_t speed = pHeader.speed;
|
||||||
|
SidTuneInfo::clock_t clock = SidTuneInfo::CLOCK_UNKNOWN;
|
||||||
|
|
||||||
|
if (info->m_songs > MAX_SONGS)
|
||||||
|
{
|
||||||
|
info->m_songs = MAX_SONGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool musPlayer = false;
|
||||||
|
|
||||||
|
if (pHeader.version >= 2)
|
||||||
|
{
|
||||||
|
const uint_least16_t flags = pHeader.flags;
|
||||||
|
if (flags & PSID_MUS)
|
||||||
|
{ // MUS tunes run at any speed
|
||||||
|
clock = SidTuneInfo::CLOCK_ANY;
|
||||||
|
musPlayer = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This flags is only available for the appropriate
|
||||||
|
// file formats
|
||||||
|
switch (compatibility)
|
||||||
|
{
|
||||||
|
case SidTuneInfo::COMPATIBILITY_C64:
|
||||||
|
if (flags & PSID_SPECIFIC)
|
||||||
|
info->m_compatibility = SidTuneInfo::COMPATIBILITY_PSID;
|
||||||
|
break;
|
||||||
|
case SidTuneInfo::COMPATIBILITY_R64:
|
||||||
|
if (flags & PSID_BASIC)
|
||||||
|
info->m_compatibility = SidTuneInfo::COMPATIBILITY_BASIC;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((flags & PSID_CLOCK_ANY) == PSID_CLOCK_ANY)
|
||||||
|
clock = SidTuneInfo::CLOCK_ANY;
|
||||||
|
else if (flags & PSID_CLOCK_PAL)
|
||||||
|
clock = SidTuneInfo::CLOCK_PAL;
|
||||||
|
else if (flags & PSID_CLOCK_NTSC)
|
||||||
|
clock = SidTuneInfo::CLOCK_NTSC;
|
||||||
|
|
||||||
|
info->m_clockSpeed = clock;
|
||||||
|
|
||||||
|
if ((flags & PSID_SIDMODEL1_ANY) == PSID_SIDMODEL1_ANY)
|
||||||
|
info->m_sidModel1 = SidTuneInfo::SIDMODEL_ANY;
|
||||||
|
else if (flags & PSID_SIDMODEL1_6581)
|
||||||
|
info->m_sidModel1 = SidTuneInfo::SIDMODEL_6581;
|
||||||
|
else if (flags & PSID_SIDMODEL1_8580)
|
||||||
|
info->m_sidModel1 = SidTuneInfo::SIDMODEL_8580;
|
||||||
|
|
||||||
|
info->m_relocStartPage = pHeader.relocStartPage;
|
||||||
|
info->m_relocPages = pHeader.relocPages;
|
||||||
|
|
||||||
|
if (pHeader.version >= 3)
|
||||||
|
{
|
||||||
|
// Only even values are valid. Ranges $00-$41 ($D000-$D410) and
|
||||||
|
// $80-$DF ($D800-$DDF0) are invalid. Any invalid value means that no second SID
|
||||||
|
// is used, like $00.
|
||||||
|
if (pHeader.sidChipBase2 & 1
|
||||||
|
|| (pHeader.sidChipBase2 >= 0x00 && pHeader.sidChipBase2 <= 0x41)
|
||||||
|
|| (pHeader.sidChipBase2 >= 0x80 && pHeader.sidChipBase2 <= 0xdf))
|
||||||
|
{
|
||||||
|
info->m_sidChipBase2 = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info->m_sidChipBase2 = 0xd000 | (pHeader.sidChipBase2 << 4);
|
||||||
|
|
||||||
|
if ((flags & PSID_SIDMODEL2_ANY) == PSID_SIDMODEL2_ANY)
|
||||||
|
info->m_sidModel2 = SidTuneInfo::SIDMODEL_ANY;
|
||||||
|
else if (flags & PSID_SIDMODEL2_6581)
|
||||||
|
info->m_sidModel2 = SidTuneInfo::SIDMODEL_6581;
|
||||||
|
else if (flags & PSID_SIDMODEL2_8580)
|
||||||
|
info->m_sidModel2 = SidTuneInfo::SIDMODEL_8580;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check reserved fields to force real c64 compliance
|
||||||
|
// as required by the RSID specification
|
||||||
|
if (compatibility == SidTuneInfo::COMPATIBILITY_R64)
|
||||||
|
{
|
||||||
|
if ((info->m_loadAddr != 0)
|
||||||
|
|| (info->m_playAddr != 0)
|
||||||
|
|| (speed != 0))
|
||||||
|
{
|
||||||
|
throw loadError(ERR_INVALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Real C64 tunes appear as CIA
|
||||||
|
speed = ~0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the speed/clock setting table.
|
||||||
|
convertOldStyleSpeedToTables(speed, clock);
|
||||||
|
|
||||||
|
// Copy info strings.
|
||||||
|
info->m_infoString.push_back(std::string(pHeader.name, PSID_MAXSTRLEN));
|
||||||
|
info->m_infoString.push_back(std::string(pHeader.author, PSID_MAXSTRLEN));
|
||||||
|
info->m_infoString.push_back(std::string(pHeader.released, PSID_MAXSTRLEN));
|
||||||
|
|
||||||
|
if (musPlayer)
|
||||||
|
throw loadError("Compute!'s Sidplayer MUS data is not supported yet"); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *PSID::createMD5(char *md5)
|
||||||
|
{
|
||||||
|
if (md5 == nullptr)
|
||||||
|
md5 = m_md5;
|
||||||
|
|
||||||
|
*md5 = '\0';
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Include C64 data.
|
||||||
|
sidmd5 myMD5;
|
||||||
|
uint8_t tmp[2];
|
||||||
|
myMD5.append(&cache[fileOffset], info->m_c64dataLen);
|
||||||
|
|
||||||
|
// Include INIT and PLAY address.
|
||||||
|
endian_little16(tmp,info->m_initAddr);
|
||||||
|
myMD5.append(tmp,sizeof(tmp));
|
||||||
|
endian_little16(tmp,info->m_playAddr);
|
||||||
|
myMD5.append(tmp,sizeof(tmp));
|
||||||
|
|
||||||
|
// Include number of songs.
|
||||||
|
endian_little16(tmp,info->m_songs);
|
||||||
|
myMD5.append(tmp,sizeof(tmp));
|
||||||
|
|
||||||
|
{ // Include song speed for each song.
|
||||||
|
const unsigned int currentSong = info->m_currentSong;
|
||||||
|
for (unsigned int s = 1; s <= info->m_songs; s++)
|
||||||
|
{
|
||||||
|
selectSong (s);
|
||||||
|
const uint_least8_t songSpeed = (uint_least8_t)info->m_songSpeed;
|
||||||
|
myMD5.append (&songSpeed,sizeof(songSpeed));
|
||||||
|
}
|
||||||
|
// Restore old song
|
||||||
|
selectSong (currentSong);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deal with PSID v2NG clock speed flags: Let only NTSC
|
||||||
|
// clock speed change the MD5 fingerprint. That way the
|
||||||
|
// fingerprint of a PAL-speed sidtune in PSID v1, v2, and
|
||||||
|
// PSID v2NG format is the same.
|
||||||
|
if (info->m_clockSpeed == SidTuneInfo::CLOCK_NTSC)
|
||||||
|
{
|
||||||
|
const uint_least8_t ntsc_val = 2;
|
||||||
|
myMD5.append (&ntsc_val,sizeof(ntsc_val));
|
||||||
|
}
|
||||||
|
|
||||||
|
// NB! If the fingerprint is used as an index into a
|
||||||
|
// song-lengths database or cache, modify above code to
|
||||||
|
// allow for PSID v2NG files which have clock speed set to
|
||||||
|
// SIDTUNE_CLOCK_ANY. If the SID player program fully
|
||||||
|
// supports the SIDTUNE_CLOCK_ANY setting, a sidtune could
|
||||||
|
// either create two different fingerprints depending on
|
||||||
|
// the clock speed chosen by the player, or there could be
|
||||||
|
// two different values stored in the database/cache.
|
||||||
|
|
||||||
|
myMD5.finish();
|
||||||
|
|
||||||
|
// Get fingerprint.
|
||||||
|
myMD5.getDigest().copy(md5, SidTune::MD5_LENGTH);
|
||||||
|
md5[SidTune::MD5_LENGTH] ='\0';
|
||||||
|
}
|
||||||
|
catch (md5Error const &) {}
|
||||||
|
|
||||||
|
return md5;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,153 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2011-2013 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
* Copyright 2007-2010 Antti Lankila
|
||||||
|
* Copyright 2000-2001 Simon White
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SIDBUILDER_H
|
||||||
|
#define SIDBUILDER_H
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "sidplayfp/SidConfig.h"
|
||||||
|
|
||||||
|
class sidemu;
|
||||||
|
class EventContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for sid builders.
|
||||||
|
*/
|
||||||
|
class sidbuilder
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
typedef std::set<sidemu*> emuset_t;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char * const m_name;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string m_errorBuffer;
|
||||||
|
|
||||||
|
emuset_t sidobjs;
|
||||||
|
|
||||||
|
bool m_status;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Utility class for setting emu parameters in builders.
|
||||||
|
*/
|
||||||
|
template<class Temu, typename Tparam>
|
||||||
|
class applyParameter
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Tparam m_param;
|
||||||
|
void (Temu::*m_method)(Tparam);
|
||||||
|
|
||||||
|
public:
|
||||||
|
applyParameter(void (Temu::*method)(Tparam), Tparam param) :
|
||||||
|
m_param(param),
|
||||||
|
m_method(method) {}
|
||||||
|
void operator() (sidemu *e) { (static_cast<Temu*>(e)->*m_method)(m_param); }
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
sidbuilder(const char * const name) :
|
||||||
|
m_name(name),
|
||||||
|
m_errorBuffer("N/A"),
|
||||||
|
m_status(true) {}
|
||||||
|
virtual ~sidbuilder() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of used devices.
|
||||||
|
*
|
||||||
|
* @return number of used sids, 0 if none.
|
||||||
|
*/
|
||||||
|
unsigned int usedDevices() const { return sidobjs.size(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available devices.
|
||||||
|
*
|
||||||
|
* @return the number of available sids, 0 = endless.
|
||||||
|
*/
|
||||||
|
virtual unsigned int availDevices() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the sid emu.
|
||||||
|
*
|
||||||
|
* @param sids the number of required sid emu
|
||||||
|
*/
|
||||||
|
virtual unsigned int create(unsigned int sids) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a free SID of the required specs
|
||||||
|
*
|
||||||
|
* @param env the event context
|
||||||
|
* @param model the required sid model
|
||||||
|
* @return pointer to the locked sid emu
|
||||||
|
*/
|
||||||
|
sidemu *lock(EventContext *env, SidConfig::sid_model_t model);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release this SID.
|
||||||
|
*
|
||||||
|
* @param device the sid emu to unlock
|
||||||
|
*/
|
||||||
|
void unlock(sidemu *device);
|
||||||
|
|
||||||
|
/** Remove all SID emulations. */
|
||||||
|
void remove();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the builder's name.
|
||||||
|
*
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
const char *name() const { return m_name; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error message.
|
||||||
|
*
|
||||||
|
* @return string error message.
|
||||||
|
*/
|
||||||
|
const char *error() const { return m_errorBuffer.c_str(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine current state of object.
|
||||||
|
*
|
||||||
|
* @return true = okay, false = error
|
||||||
|
*/
|
||||||
|
bool getStatus() const { return m_status; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the builder's credits.
|
||||||
|
*
|
||||||
|
* @return credits
|
||||||
|
*/
|
||||||
|
virtual const char *credits() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle sid filter emulation.
|
||||||
|
*
|
||||||
|
* @param enable true = enable, false = disable
|
||||||
|
*/
|
||||||
|
virtual void filter(bool enable) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SIDBUILDER_H
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -0,0 +1,9 @@
|
||||||
|
[Filter]
|
||||||
|
DistortionAttenuation=0.50
|
||||||
|
DistortionNonlinearity=3.3e6
|
||||||
|
VoiceNonlinearity =1.80
|
||||||
|
Type3BaseResistance =1.3e6
|
||||||
|
Type3Offset =3.7e8
|
||||||
|
Type3Steepness =1.0066
|
||||||
|
Type3MinimumFETResistance=1.8e4
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,223 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2011-2014 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
* Copyright 2009-2014 VICE Project
|
||||||
|
* Copyright 2007-2010 Antti Lankila
|
||||||
|
* Copyright 2000 Simon White
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "tod.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "mos6526.h"
|
||||||
|
|
||||||
|
namespace libsidplayfp
|
||||||
|
{
|
||||||
|
|
||||||
|
void Tod::reset()
|
||||||
|
{
|
||||||
|
cycles = 0;
|
||||||
|
|
||||||
|
memset(clock, 0, sizeof(clock));
|
||||||
|
clock[HOURS] = 1; // the most common value
|
||||||
|
memcpy(latch, clock, sizeof(latch));
|
||||||
|
memset(alarm, 0, sizeof(alarm));
|
||||||
|
|
||||||
|
isLatched = false;
|
||||||
|
isStopped = true;
|
||||||
|
|
||||||
|
event_context.schedule(*this, 0, EVENT_CLOCK_PHI1);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Tod::read(uint_least8_t reg)
|
||||||
|
{
|
||||||
|
// TOD clock is latched by reading Hours, and released
|
||||||
|
// upon reading Tenths of Seconds. The counter itself
|
||||||
|
// keeps ticking all the time.
|
||||||
|
// Also note that this latching is different from the input one.
|
||||||
|
if (!isLatched)
|
||||||
|
memcpy(latch, clock, sizeof(latch));
|
||||||
|
|
||||||
|
if (reg == TENTHS)
|
||||||
|
isLatched = false;
|
||||||
|
else if (reg == HOURS)
|
||||||
|
isLatched = true;
|
||||||
|
|
||||||
|
return latch[reg];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tod::write(uint_least8_t reg, uint8_t data)
|
||||||
|
{
|
||||||
|
switch (reg)
|
||||||
|
{
|
||||||
|
case TENTHS: // Time Of Day clock 1/10 s
|
||||||
|
data &= 0x0f;
|
||||||
|
break;
|
||||||
|
case SECONDS: // Time Of Day clock sec
|
||||||
|
// deliberate run on
|
||||||
|
case MINUTES: // Time Of Day clock min
|
||||||
|
data &= 0x7f;
|
||||||
|
break;
|
||||||
|
case HOURS: // Time Of Day clock hour
|
||||||
|
// force bits 6-5 = 0
|
||||||
|
data &= 0x9f;
|
||||||
|
// Flip AM/PM on hour 12
|
||||||
|
// Flip AM/PM only when writing time, not when writing alarm
|
||||||
|
if ((data & 0x1f) == 0x12 && !(crb & 0x80))
|
||||||
|
data ^= 0x80;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
|
if (crb & 0x80)
|
||||||
|
{
|
||||||
|
// set alarm
|
||||||
|
if (alarm[reg] != data)
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
alarm[reg] = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// set time
|
||||||
|
if (reg == TENTHS)
|
||||||
|
{
|
||||||
|
// apparently the tickcounter is reset to 0 when the clock
|
||||||
|
// is not running and then restarted by writing to the 10th
|
||||||
|
// seconds register.
|
||||||
|
if (isStopped)
|
||||||
|
{
|
||||||
|
cycles = 0;
|
||||||
|
isStopped = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (reg == HOURS)
|
||||||
|
{
|
||||||
|
isStopped = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clock[reg] != data)
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
clock[reg] = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check alarm
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
checkAlarm();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tod::event()
|
||||||
|
{
|
||||||
|
// Reload divider according to 50/60 Hz flag
|
||||||
|
// Only performed on expiry according to Frodo
|
||||||
|
cycles += period * (cra & 0x80 ? 5 : 6);
|
||||||
|
|
||||||
|
// Fixed precision 25.7
|
||||||
|
event_context.schedule(*this, cycles >> 7);
|
||||||
|
cycles &= 0x7F; // Just keep the decimal part
|
||||||
|
|
||||||
|
if (!isStopped)
|
||||||
|
{
|
||||||
|
// advance the counters.
|
||||||
|
// - individual counters are all 4 bit
|
||||||
|
uint8_t t0 = clock[TENTHS] & 0x0f;
|
||||||
|
uint8_t t1 = clock[SECONDS] & 0x0f;
|
||||||
|
uint8_t t2 = (clock[SECONDS] >> 4) & 0x0f;
|
||||||
|
uint8_t t3 = clock[MINUTES] & 0x0f;
|
||||||
|
uint8_t t4 = (clock[MINUTES] >> 4) & 0x0f;
|
||||||
|
uint8_t t5 = clock[HOURS] & 0x0f;
|
||||||
|
uint8_t t6 = (clock[HOURS] >> 4) & 0x01;
|
||||||
|
uint8_t pm = clock[HOURS] & 0x80;
|
||||||
|
|
||||||
|
// tenth seconds (0-9)
|
||||||
|
t0 = (t0 + 1) & 0x0f;
|
||||||
|
if (t0 == 10)
|
||||||
|
{
|
||||||
|
t0 = 0;
|
||||||
|
// seconds (0-59)
|
||||||
|
t1 = (t1 + 1) & 0x0f; // x0...x9
|
||||||
|
if (t1 == 10)
|
||||||
|
{
|
||||||
|
t1 = 0;
|
||||||
|
t2 = (t2 + 1) & 0x07; // 0x...5x
|
||||||
|
if (t2 == 6)
|
||||||
|
{
|
||||||
|
t2 = 0;
|
||||||
|
// minutes (0-59)
|
||||||
|
t3 = (t3 + 1) & 0x0f; // x0...x9
|
||||||
|
if (t3 == 10)
|
||||||
|
{
|
||||||
|
t3 = 0;
|
||||||
|
t4 = (t4 + 1) & 0x07; // 0x...5x
|
||||||
|
if (t4 == 6)
|
||||||
|
{
|
||||||
|
t4 = 0;
|
||||||
|
// hours (1-12)
|
||||||
|
t5 = (t5 + 1) & 0x0f;
|
||||||
|
if (t6)
|
||||||
|
{
|
||||||
|
// toggle the am/pm flag when going from 11 to 12 (!)
|
||||||
|
if (t5 == 2)
|
||||||
|
{
|
||||||
|
pm ^= 0x80;
|
||||||
|
}
|
||||||
|
// wrap 12h -> 1h (FIXME: when hour became x3 ?)
|
||||||
|
if (t5 == 3)
|
||||||
|
{
|
||||||
|
t5 = 1;
|
||||||
|
t6 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (t5 == 10)
|
||||||
|
{
|
||||||
|
t5 = 0;
|
||||||
|
t6 = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clock[TENTHS] = t0;
|
||||||
|
clock[SECONDS] = t1 | (t2 << 4);
|
||||||
|
clock[MINUTES] = t3 | (t4 << 4);
|
||||||
|
clock[HOURS] = t5 | (t6 << 4) | pm;
|
||||||
|
|
||||||
|
checkAlarm();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tod::checkAlarm()
|
||||||
|
{
|
||||||
|
if (!memcmp(alarm, clock, sizeof(alarm)))
|
||||||
|
{
|
||||||
|
parent->todInterrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,276 @@
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// This file is part of reSID, a MOS6581 SID emulator engine.
|
||||||
|
// Copyright (C) 2010 Dag Lem <resid@nimrod.no>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef RESID_SPLINE_H
|
||||||
|
#define RESID_SPLINE_H
|
||||||
|
|
||||||
|
namespace reSID
|
||||||
|
{
|
||||||
|
|
||||||
|
// Our objective is to construct a smooth interpolating single-valued function
|
||||||
|
// y = f(x).
|
||||||
|
//
|
||||||
|
// Catmull-Rom splines are widely used for interpolation, however these are
|
||||||
|
// parametric curves [x(t) y(t) ...] and can not be used to directly calculate
|
||||||
|
// y = f(x).
|
||||||
|
// For a discussion of Catmull-Rom splines see Catmull, E., and R. Rom,
|
||||||
|
// "A Class of Local Interpolating Splines", Computer Aided Geometric Design.
|
||||||
|
//
|
||||||
|
// Natural cubic splines are single-valued functions, and have been used in
|
||||||
|
// several applications e.g. to specify gamma curves for image display.
|
||||||
|
// These splines do not afford local control, and a set of linear equations
|
||||||
|
// including all interpolation points must be solved before any point on the
|
||||||
|
// curve can be calculated. The lack of local control makes the splines
|
||||||
|
// more difficult to handle than e.g. Catmull-Rom splines, and real-time
|
||||||
|
// interpolation of a stream of data points is not possible.
|
||||||
|
// For a discussion of natural cubic splines, see e.g. Kreyszig, E., "Advanced
|
||||||
|
// Engineering Mathematics".
|
||||||
|
//
|
||||||
|
// Our approach is to approximate the properties of Catmull-Rom splines for
|
||||||
|
// piecewice cubic polynomials f(x) = ax^3 + bx^2 + cx + d as follows:
|
||||||
|
// Each curve segment is specified by four interpolation points,
|
||||||
|
// p0, p1, p2, p3.
|
||||||
|
// The curve between p1 and p2 must interpolate both p1 and p2, and in addition
|
||||||
|
// f'(p1.x) = k1 = (p2.y - p0.y)/(p2.x - p0.x) and
|
||||||
|
// f'(p2.x) = k2 = (p3.y - p1.y)/(p3.x - p1.x).
|
||||||
|
//
|
||||||
|
// The constraints are expressed by the following system of linear equations
|
||||||
|
//
|
||||||
|
// [ 1 xi xi^2 xi^3 ] [ d ] [ yi ]
|
||||||
|
// [ 1 2*xi 3*xi^2 ] * [ c ] = [ ki ]
|
||||||
|
// [ 1 xj xj^2 xj^3 ] [ b ] [ yj ]
|
||||||
|
// [ 1 2*xj 3*xj^2 ] [ a ] [ kj ]
|
||||||
|
//
|
||||||
|
// Solving using Gaussian elimination and back substitution, setting
|
||||||
|
// dy = yj - yi, dx = xj - xi, we get
|
||||||
|
//
|
||||||
|
// a = ((ki + kj) - 2*dy/dx)/(dx*dx);
|
||||||
|
// b = ((kj - ki)/dx - 3*(xi + xj)*a)/2;
|
||||||
|
// c = ki - (3*xi*a + 2*b)*xi;
|
||||||
|
// d = yi - ((xi*a + b)*xi + c)*xi;
|
||||||
|
//
|
||||||
|
// Having calculated the coefficients of the cubic polynomial we have the
|
||||||
|
// choice of evaluation by brute force
|
||||||
|
//
|
||||||
|
// for (x = x1; x <= x2; x += res) {
|
||||||
|
// y = ((a*x + b)*x + c)*x + d;
|
||||||
|
// plot(x, y);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// or by forward differencing
|
||||||
|
//
|
||||||
|
// y = ((a*x1 + b)*x1 + c)*x1 + d;
|
||||||
|
// dy = (3*a*(x1 + res) + 2*b)*x1*res + ((a*res + b)*res + c)*res;
|
||||||
|
// d2y = (6*a*(x1 + res) + 2*b)*res*res;
|
||||||
|
// d3y = 6*a*res*res*res;
|
||||||
|
//
|
||||||
|
// for (x = x1; x <= x2; x += res) {
|
||||||
|
// plot(x, y);
|
||||||
|
// y += dy; dy += d2y; d2y += d3y;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// See Foley, Van Dam, Feiner, Hughes, "Computer Graphics, Principles and
|
||||||
|
// Practice" for a discussion of forward differencing.
|
||||||
|
//
|
||||||
|
// If we have a set of interpolation points p0, ..., pn, we may specify
|
||||||
|
// curve segments between p0 and p1, and between pn-1 and pn by using the
|
||||||
|
// following constraints:
|
||||||
|
// f''(p0.x) = 0 and
|
||||||
|
// f''(pn.x) = 0.
|
||||||
|
//
|
||||||
|
// Substituting the results for a and b in
|
||||||
|
//
|
||||||
|
// 2*b + 6*a*xi = 0
|
||||||
|
//
|
||||||
|
// we get
|
||||||
|
//
|
||||||
|
// ki = (3*dy/dx - kj)/2;
|
||||||
|
//
|
||||||
|
// or by substituting the results for a and b in
|
||||||
|
//
|
||||||
|
// 2*b + 6*a*xj = 0
|
||||||
|
//
|
||||||
|
// we get
|
||||||
|
//
|
||||||
|
// kj = (3*dy/dx - ki)/2;
|
||||||
|
//
|
||||||
|
// Finally, if we have only two interpolation points, the cubic polynomial
|
||||||
|
// will degenerate to a straight line if we set
|
||||||
|
//
|
||||||
|
// ki = kj = dy/dx;
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#if SPLINE_BRUTE_FORCE
|
||||||
|
#define interpolate_segment interpolate_brute_force
|
||||||
|
#else
|
||||||
|
#define interpolate_segment interpolate_forward_difference
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Calculation of coefficients.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
inline
|
||||||
|
void cubic_coefficients(double x1, double y1, double x2, double y2,
|
||||||
|
double k1, double k2,
|
||||||
|
double& a, double& b, double& c, double& d)
|
||||||
|
{
|
||||||
|
double dx = x2 - x1, dy = y2 - y1;
|
||||||
|
|
||||||
|
a = ((k1 + k2) - 2*dy/dx)/(dx*dx);
|
||||||
|
b = ((k2 - k1)/dx - 3*(x1 + x2)*a)/2;
|
||||||
|
c = k1 - (3*x1*a + 2*b)*x1;
|
||||||
|
d = y1 - ((x1*a + b)*x1 + c)*x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Evaluation of cubic polynomial by brute force.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
template<class PointPlotter>
|
||||||
|
inline
|
||||||
|
void interpolate_brute_force(double x1, double y1, double x2, double y2,
|
||||||
|
double k1, double k2,
|
||||||
|
PointPlotter plot, double res)
|
||||||
|
{
|
||||||
|
double a, b, c, d;
|
||||||
|
cubic_coefficients(x1, y1, x2, y2, k1, k2, a, b, c, d);
|
||||||
|
|
||||||
|
// Calculate each point.
|
||||||
|
for (double x = x1; x <= x2; x += res) {
|
||||||
|
double y = ((a*x + b)*x + c)*x + d;
|
||||||
|
plot(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Evaluation of cubic polynomial by forward differencing.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
template<class PointPlotter>
|
||||||
|
inline
|
||||||
|
void interpolate_forward_difference(double x1, double y1, double x2, double y2,
|
||||||
|
double k1, double k2,
|
||||||
|
PointPlotter plot, double res)
|
||||||
|
{
|
||||||
|
double a, b, c, d;
|
||||||
|
cubic_coefficients(x1, y1, x2, y2, k1, k2, a, b, c, d);
|
||||||
|
|
||||||
|
double y = ((a*x1 + b)*x1 + c)*x1 + d;
|
||||||
|
double dy = (3*a*(x1 + res) + 2*b)*x1*res + ((a*res + b)*res + c)*res;
|
||||||
|
double d2y = (6*a*(x1 + res) + 2*b)*res*res;
|
||||||
|
double d3y = 6*a*res*res*res;
|
||||||
|
|
||||||
|
// Calculate each point.
|
||||||
|
for (double x = x1; x <= x2; x += res) {
|
||||||
|
plot(x, y);
|
||||||
|
y += dy; dy += d2y; d2y += d3y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class PointIter>
|
||||||
|
inline
|
||||||
|
double x(PointIter p)
|
||||||
|
{
|
||||||
|
return (*p)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class PointIter>
|
||||||
|
inline
|
||||||
|
double y(PointIter p)
|
||||||
|
{
|
||||||
|
return (*p)[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Evaluation of complete interpolating function.
|
||||||
|
// Note that since each curve segment is controlled by four points, the
|
||||||
|
// end points will not be interpolated. If extra control points are not
|
||||||
|
// desirable, the end points can simply be repeated to ensure interpolation.
|
||||||
|
// Note also that points of non-differentiability and discontinuity can be
|
||||||
|
// introduced by repeating points.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
template<class PointIter, class PointPlotter>
|
||||||
|
inline
|
||||||
|
void interpolate(PointIter p0, PointIter pn, PointPlotter plot, double res)
|
||||||
|
{
|
||||||
|
double k1, k2;
|
||||||
|
|
||||||
|
// Set up points for first curve segment.
|
||||||
|
PointIter p1 = p0; ++p1;
|
||||||
|
PointIter p2 = p1; ++p2;
|
||||||
|
PointIter p3 = p2; ++p3;
|
||||||
|
|
||||||
|
// Draw each curve segment.
|
||||||
|
for (; p2 != pn; ++p0, ++p1, ++p2, ++p3) {
|
||||||
|
// p1 and p2 equal; single point.
|
||||||
|
if (x(p1) == x(p2)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Both end points repeated; straight line.
|
||||||
|
if (x(p0) == x(p1) && x(p2) == x(p3)) {
|
||||||
|
k1 = k2 = (y(p2) - y(p1))/(x(p2) - x(p1));
|
||||||
|
}
|
||||||
|
// p0 and p1 equal; use f''(x1) = 0.
|
||||||
|
else if (x(p0) == x(p1)) {
|
||||||
|
k2 = (y(p3) - y(p1))/(x(p3) - x(p1));
|
||||||
|
k1 = (3*(y(p2) - y(p1))/(x(p2) - x(p1)) - k2)/2;
|
||||||
|
}
|
||||||
|
// p2 and p3 equal; use f''(x2) = 0.
|
||||||
|
else if (x(p2) == x(p3)) {
|
||||||
|
k1 = (y(p2) - y(p0))/(x(p2) - x(p0));
|
||||||
|
k2 = (3*(y(p2) - y(p1))/(x(p2) - x(p1)) - k1)/2;
|
||||||
|
}
|
||||||
|
// Normal curve.
|
||||||
|
else {
|
||||||
|
k1 = (y(p2) - y(p0))/(x(p2) - x(p0));
|
||||||
|
k2 = (y(p3) - y(p1))/(x(p3) - x(p1));
|
||||||
|
}
|
||||||
|
|
||||||
|
interpolate_segment(x(p1), y(p1), x(p2), y(p2), k1, k2, plot, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Class for plotting integers into an array.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
template<class F>
|
||||||
|
class PointPlotter
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
F* f;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PointPlotter(F* arr) : f(arr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator ()(double x, double y)
|
||||||
|
{
|
||||||
|
// Clamp negative values to zero.
|
||||||
|
if (y < 0) {
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
f[int(x)] = F(y + 0.5);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace reSID
|
||||||
|
|
||||||
|
#endif // not RESID_SPLINE_H
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,469 @@
|
||||||
|
2010-??-?? Dag Lem <resid@nimrod.no>
|
||||||
|
|
||||||
|
* Version 1.0 released.
|
||||||
|
|
||||||
|
* configure.ac: Updated to current autoconf/automake standards.
|
||||||
|
New option --enable-arch for gcc architecture specific
|
||||||
|
optimizations, including vectorization. New option
|
||||||
|
--enable-branch-hints for branch prediction optimizations.
|
||||||
|
|
||||||
|
* Makefile.am, samp2src.pl: Generate header files instead of
|
||||||
|
source files for waveform samples. Added dac.h, dac.cc.
|
||||||
|
|
||||||
|
* siddefs.h.in: Sampling method names now better reflect their
|
||||||
|
operation (SAMPLE_RESAMPLE_INTERPOLATE -> SAMPLE_RESAMPLE,
|
||||||
|
SAMPLE_RESAMPLE_FAST -> SAMPLE_RESAMPLE_FASTMEM).
|
||||||
|
New macros for branch prediction: likely / unlikely.
|
||||||
|
|
||||||
|
* dac.h: New file; accurate emulation of non-monotonic MOS 6581
|
||||||
|
D/A converters.
|
||||||
|
|
||||||
|
* dac.cc: New file; accurate emulation of non-monotonic MOS 6581
|
||||||
|
D/A converters.
|
||||||
|
|
||||||
|
* envelope.h (EnvelopeGenerator::clock): Emulation of one cycle
|
||||||
|
pipeline delay in the exponential frequency divider.
|
||||||
|
(EnvelopeGenerator::output): Emulation of non-ideal DAC output.
|
||||||
|
(EnvelopeGenerator::set_chip_model): New function; for emulation
|
||||||
|
of DAC imperfections.
|
||||||
|
(EnvelopeGenerator::set_exponential_counter): New function;
|
||||||
|
modularization of exponential counter update.
|
||||||
|
|
||||||
|
* envelope.cc (EnvelopeGenerator::EnvelopeGenerator):
|
||||||
|
Initialization of DAC lookup tables.
|
||||||
|
(EnvelopeGenerator::readENV): Return envelope_counter directly, in
|
||||||
|
order to allow EnvelopeGenerator::output to emulate DAC
|
||||||
|
imperfections.
|
||||||
|
(EnvelopeGenerator::reset): Initialization of new
|
||||||
|
variables.
|
||||||
|
(EnvelopeGenerator::set_chip_model): New function; for emulation
|
||||||
|
of DAC imperfections.
|
||||||
|
(EnvelopeGenerator::writeCONTROL_REG): Flush of exponential
|
||||||
|
frequency divider pipeline on attack.
|
||||||
|
|
||||||
|
* extfilt.h (ExternalFilter::clock): Cutoff frequency fixed point
|
||||||
|
accuracy is traded off for for vastly improved filter signal
|
||||||
|
fixed point accuracy.
|
||||||
|
(ExternalFilter::output): Output range reduced from 20 to 16
|
||||||
|
bits.
|
||||||
|
|
||||||
|
* extfilt.cc (ExternalFilter::ExternalFilter): Assumes audio
|
||||||
|
equipment impedance of 10kOhm, yielding a high-pass 3-dB frequency
|
||||||
|
of 1.6Hz (changed from 16Hz). Cutoff frequency fixed point accuracy
|
||||||
|
is traded off for for vastly improved filter signal fixed point
|
||||||
|
accuracy.
|
||||||
|
(ExternalFilter::set_chip_model): Removed. Remaining DC levels can
|
||||||
|
only be canceled by enabling the external filter (or by similar
|
||||||
|
post processing).
|
||||||
|
|
||||||
|
* filter.h: Major rewrite implementing an accurate model of the
|
||||||
|
actual filter and output stage topology, including models for
|
||||||
|
op-amps, input and feedback NMOS FET "resistors", and voltage
|
||||||
|
controlled resistors (VCRs).
|
||||||
|
(Filter::input): New interface to set external input level.
|
||||||
|
(Filter::output): Output range reduced from 20 to 16 bits.
|
||||||
|
(Filter::set_voice_mask): New function. Emulation of physical
|
||||||
|
connection of EXT IN, and voice muting for test purposes.
|
||||||
|
(Filter::solve_gain): New function; iterative solver using
|
||||||
|
Newton-Raphson and bisection to calculate gain for SID op-amp
|
||||||
|
gains and summers using NMOS FETs as input and feedback "resistors".
|
||||||
|
(Filter::solve_integrate): New function; one-step fixpoint solver
|
||||||
|
to calculate output from SID op-amp integrators using VCRs built
|
||||||
|
from four NMOS FETs as inputs.
|
||||||
|
|
||||||
|
* filter.cc: Major rewrite implementing an accurate model of the
|
||||||
|
actual filter and output stage topology, including models for
|
||||||
|
op-amps, input and feedback NMOS FET "resistors", and voltage
|
||||||
|
controlled resistors (VCRs).
|
||||||
|
(Filter::set_voice_mask): New function. Emulation of physical
|
||||||
|
connection of EXT IN, and voice muting for test purposes.
|
||||||
|
|
||||||
|
* sid.h: Resampling constants declared in enum.
|
||||||
|
(SID::State): Added voice_mask, shift_register_reset,
|
||||||
|
shift_pipeline, pulse_output, floating_output_ttl,
|
||||||
|
envelope_pipeline.
|
||||||
|
(SID::output): 16 bit output range only, n-bit interface
|
||||||
|
removed.
|
||||||
|
(SID::clock_resample): Renamed from
|
||||||
|
SID::clock_resample_interpolate.
|
||||||
|
(SID::clock_resample_fastmem): Renamed from
|
||||||
|
SID::clock_resample_fast.
|
||||||
|
|
||||||
|
* sid.cc (SID::clock): Emulation of one cycle pipeline write delay
|
||||||
|
for the MOS8580.
|
||||||
|
(SID::clock_resample): Renamed from SID::clock_resample_interpolate.
|
||||||
|
Corrected bug in FIR table wraparound, courtesy of Antti Lankila.
|
||||||
|
(SID::clock_resample_fastmem): Renamed from
|
||||||
|
SID::clock_resample_fast.
|
||||||
|
(SID::input): Hand off all processing of the external input to the
|
||||||
|
filter.
|
||||||
|
(SID::output): 16 bit output range only, n-bit output interface
|
||||||
|
removed.
|
||||||
|
(SID::read): Aging time for bus value increased from 0x2000 to
|
||||||
|
0x4000 cycles.
|
||||||
|
(SID::read_state, SID::write_state): Added voice_mask,
|
||||||
|
shift_register_reset, shift_pipeline, pulse_output,
|
||||||
|
floating_output_ttl, envelope_pipeline.
|
||||||
|
(SID::set_voice_mask): New function. Emulation of physical
|
||||||
|
connection of EXT IN, and voice muting for test purposes.
|
||||||
|
(SID::write): Emulation of one cycle pipeline write delay for the
|
||||||
|
MOS8580.
|
||||||
|
(SID::write_pipeline): New function. Emulation of one cycle
|
||||||
|
pipeline write delay for the MOS8580.
|
||||||
|
|
||||||
|
* spline.h (PointPlotter::operator()): Rounding to nearest
|
||||||
|
integer.
|
||||||
|
|
||||||
|
* voice.h (Voice::output): Handling of DC for waveform "zero"
|
||||||
|
level moved to Filter::clock.
|
||||||
|
|
||||||
|
* voice.cc (Voice::set_chip_model): Call set_chip_model for
|
||||||
|
envelope generator. Handling of DC for "zero" level moved to
|
||||||
|
Filter::set_chip_model.
|
||||||
|
|
||||||
|
* wave.h (WaveformGenerator::clock): Corrected shift register
|
||||||
|
model. Emulation of reset time for the shift register. Emulation
|
||||||
|
of two cycle pipeline delay for accumulator bit 19 to shift the
|
||||||
|
shift register.
|
||||||
|
(WaveformGenerator::clock_shift_register)
|
||||||
|
(WaveformGenerator::write_shift_register)
|
||||||
|
(WaveformGenerator::reset_shift_register)
|
||||||
|
(WaveformGenerator::set_noise_output): New functions. Emulation
|
||||||
|
of writes to the shift register by combined waveforms.
|
||||||
|
(WaveformGenerator::set_waveform_output): New function. Emulation
|
||||||
|
of floating DAC input with aging. Emulation of one cycle pipeline
|
||||||
|
delay for the pulse width comparator to change the pulse
|
||||||
|
level. Emulation of writes to the shift register by combined
|
||||||
|
waveforms. Highly optimized waveform calculation using nearly
|
||||||
|
branch-free table lookup for all waveforms; replaces 16 previous
|
||||||
|
waveform functions named WaveformGenerator::outputXXXX.
|
||||||
|
(WaveformGenerator::output): Emulation of non-ideal DAC output.
|
||||||
|
|
||||||
|
* wave.cc (WaveformGenerator::WaveformGenerator): Initialization
|
||||||
|
of lookup tables for basic waveforms and DACs.
|
||||||
|
(WaveformGenerator::readOSC): Return waveform_output directly, in
|
||||||
|
order to allow WaveformGenerator::output to emulate DAC
|
||||||
|
imperfections.
|
||||||
|
(WaveformGenerator::set_chip_model): Update pointer to current
|
||||||
|
waveform table.
|
||||||
|
(WaveformGenerator::writePW_LO, WaveformGenerator::writePW_HI):
|
||||||
|
Push next pulse level into pulse level pipeline.
|
||||||
|
(WaveformGenerator::writeCONTROL_REG): Emulation of the effects of
|
||||||
|
the test bit on the shift register (shifting, reset time).
|
||||||
|
Emulation of fading time for floating DAC input (waveform 0).
|
||||||
|
Update pointer to current waveform table.
|
||||||
|
(WaveformGenerator::reset): Initialization of new variables.
|
||||||
|
|
||||||
|
2004-06-11 Dag Lem <resid@nimrod.no>
|
||||||
|
|
||||||
|
* Version 0.16 released.
|
||||||
|
|
||||||
|
* envelope.h (EnvelopeGenerator::clock): Corrected off-by-one
|
||||||
|
error in check for ADSR delay bug in delta_t cycle interface.
|
||||||
|
|
||||||
|
* filter.cc (Filter::set_chip_model): Initialize filter cutoff
|
||||||
|
mappings before call to set_chip_model.
|
||||||
|
|
||||||
|
* sid.cc (SID::set_sampling_parameters): Build shifted FIR tables
|
||||||
|
with samples according to the sampling frequency.
|
||||||
|
(SID::clock_resample_interpolate): New function; factorized linear
|
||||||
|
interpolation out from filter convolutions, and made convolutions
|
||||||
|
vectorizable.
|
||||||
|
(SID::clock_resample_fast): New function; single convolution, same
|
||||||
|
accuracy as with interpolation by using more filter tables.
|
||||||
|
(SID::State, SID::read_state, SID::write_state): Read and write
|
||||||
|
rate_counter_period and exponential_counter_period. Read sustain
|
||||||
|
value.
|
||||||
|
|
||||||
|
2003-10-20 Dag Lem <resid@nimrod.no>
|
||||||
|
|
||||||
|
* Version 0.15 released.
|
||||||
|
|
||||||
|
* envelope.h (EnvelopeGenerator): Added public State enum.
|
||||||
|
(EnvelopeGenerator::clock): Rate counter is 15 bits, count
|
||||||
|
rate_period - 1 after wrapping from 0x8000 to 0 in ADSR delay bug.
|
||||||
|
|
||||||
|
* sid.cc, sid.h (SID::State): Added envelope_state.
|
||||||
|
(SID::State::write_state): Restore register 0x18.
|
||||||
|
(SID::set_sampling_parameters): Scale resampling filter to avoid
|
||||||
|
clipping.
|
||||||
|
(SID::clock_resample): Saturated arithmetics to avoid clipping.
|
||||||
|
|
||||||
|
2002-12-31 Dag Lem <resid@nimrod.no>
|
||||||
|
|
||||||
|
* Version 0.14 released.
|
||||||
|
|
||||||
|
* envelope.h (EnvelopeGenerator::clock): Corrected one cycle error
|
||||||
|
in ADSR delay bug. Only load the exponential counter period at the
|
||||||
|
envelope counter values 255, 93, 54, 26, 14, 6, 0.
|
||||||
|
|
||||||
|
* filter.cc (Filter::set_chip_model): Call set_w0() and set_Q() to
|
||||||
|
update filter settings.
|
||||||
|
(Filter::set_w0): Limit cutoff frequency for both 1 cycle and
|
||||||
|
delta_t cycle filter.
|
||||||
|
|
||||||
|
* filter.h (Filter::clock): Mix in external audio input.
|
||||||
|
|
||||||
|
* sid.cc, sid.h (SID::input): New function; accepts external audio
|
||||||
|
input sample.
|
||||||
|
|
||||||
|
* spline.h (PointPlotter::operator ()): Clamp negative values to
|
||||||
|
zero.
|
||||||
|
|
||||||
|
* voice.cc, voice.h: Changed misleading name wave_DC to wave_zero.
|
||||||
|
|
||||||
|
* wave.h (WaveformGenerator::clock): Corrected bug in check for
|
||||||
|
accumulator bit 19 in noise register shift.
|
||||||
|
|
||||||
|
2002-01-19 Dag Lem <resid@nimrod.no>
|
||||||
|
|
||||||
|
* Version 0.13 released.
|
||||||
|
|
||||||
|
* configure.in: Replaced AC_TRY_COMPILER with AC_TRY_COMPILE,
|
||||||
|
removed AC_PROG_RANLIB.
|
||||||
|
|
||||||
|
* envelope.h (EnvelopeGenerator::clock): Reset rate_step on state
|
||||||
|
change.
|
||||||
|
|
||||||
|
* extfilt.cc (ExternalFilter::set_chip_model): New calculation of
|
||||||
|
maximum mixer DC level.
|
||||||
|
|
||||||
|
* filter.cc (Filter::set_chip_model): Moved calculation of
|
||||||
|
voice_DC to voice.cc, corrected calculation of mixer_DC.
|
||||||
|
|
||||||
|
* filter.h (Filter::output): Mixer output is not inverted.
|
||||||
|
|
||||||
|
* sid.cc (SID::set_chip_model): Call voice.set_chip_model instead
|
||||||
|
of voice.wave.set_chip_model.
|
||||||
|
|
||||||
|
* voice.cc (Voice::Voice): Call set_chip_model.
|
||||||
|
(Voice::set_chip_model): New function; model both waveform D/A
|
||||||
|
converter and envelope multiplying D/A converter DC offsets.
|
||||||
|
|
||||||
|
* voice.h (Voice::output): Add both waveform D/A converter and
|
||||||
|
envelope multiplying D/A converter DC offsets.
|
||||||
|
|
||||||
|
* wave.h (WaveformGenerator::output____): Reverted to output
|
||||||
|
minimum wave level when no waveform is selected. The maximum and
|
||||||
|
minimum wave output levels are interchanged in C= Hacking Issue #20.
|
||||||
|
|
||||||
|
2001-10-20 Dag Lem <resid@nimrod.no>
|
||||||
|
|
||||||
|
* Version 0.12 released.
|
||||||
|
|
||||||
|
* envelope.cc, envelope.h, filter.cc, filter.h, wave.cc, wave.h:
|
||||||
|
Removed bool usage. This avoids unnecessary conversion to 1/0.
|
||||||
|
|
||||||
|
* filter.cc (Filter::set_chip_model): New function; selects voice
|
||||||
|
and mixer DC offsets and mapping from the FC registers to filter
|
||||||
|
cutoff frequency. The voice and mixer DC offsets for the MOS6581 are
|
||||||
|
calculated from measurements made by Hársfalvi, Levente in
|
||||||
|
C= Hacking Issue #20.
|
||||||
|
(Filter::Filter): Call set_chip_model.
|
||||||
|
(Filter::f0_6581, Filter::f0_8580): Separate FC mapping tables.
|
||||||
|
(Filter::f0_points_6581, Filter::f0_points_8580): Separate FC mapping
|
||||||
|
points.
|
||||||
|
|
||||||
|
* extfilt.cc, extfilt.h (ExternalFilter::set_chip_model): New
|
||||||
|
function supporting separate DC correction for MOS6581 and MOS8580.
|
||||||
|
|
||||||
|
* sid.cc, sid.h (SID::adjust_sampling_frequency): New function for
|
||||||
|
on-the-fly adjustment of sampling frequency.
|
||||||
|
(SID::clock_fast): Corrected sample calculation.
|
||||||
|
(SID::set_chip_model): Set filter chip model.
|
||||||
|
(SID::output): Added audio clipping.
|
||||||
|
(SID::clock, SID::clock_fast, SID::clock_interpolate,
|
||||||
|
SID::clock_resample): Added sample interleaving.
|
||||||
|
|
||||||
|
* spline.h (interpolate): Generalized to accept repeated points to
|
||||||
|
introduce points of non-differentiability and discontinuity.
|
||||||
|
|
||||||
|
* wave.h (WaveformGenerator::output____): No selected waveform
|
||||||
|
yields maximum wave output level. This was found by Hársfalvi,
|
||||||
|
Levente in C= Hacking Issue #20.
|
||||||
|
(WaveformGenerator::clock): Optimized for speed (no division).
|
||||||
|
|
||||||
|
2001-03-10 Dag Lem <resid@nimrod.no>
|
||||||
|
|
||||||
|
* Version 0.11 released.
|
||||||
|
|
||||||
|
* configure.in: Disable building of shared library by default.
|
||||||
|
Control inlining with RESID_INLINING (0 or 1) and RESID_INLINE
|
||||||
|
(blank or "inline").
|
||||||
|
|
||||||
|
* envelope.h, extfilt.h, filter.h, voice.h, wave.h: inline keyword
|
||||||
|
in both function declarations and function definitions.
|
||||||
|
|
||||||
|
* samp2src.pl: Beautified Perl code.
|
||||||
|
|
||||||
|
* sid.h, sid.cc: Replaced voice variables with array. Removed
|
||||||
|
filter variables from SID::State.
|
||||||
|
(SID::clock): New audio sample generating interface. Three
|
||||||
|
clocking methods are available; clocking at output sample
|
||||||
|
frequency, clocking at cycle frequency with linear sample
|
||||||
|
interpolation, and clocking at cycle frequency with audio
|
||||||
|
resampling.
|
||||||
|
(SID::clock_fast, SID::clock_interpolate, SID::clock_resample):
|
||||||
|
New functions called by SID::clock.
|
||||||
|
(SID::set_sampling_parameters): New function to set up SID for
|
||||||
|
sample generation. The FIR table used in SID::clock_resample is
|
||||||
|
calculated here.
|
||||||
|
(SID::I0): 0th order modified Bessel function to calculate Kaiser
|
||||||
|
window.
|
||||||
|
|
||||||
|
* siddefs.h: Control inlining with RESID_INLINING (0 or 1) and
|
||||||
|
RESID_INLINE (blank or "inline"). Added enum sampling_method.
|
||||||
|
|
||||||
|
* voice.h, voice.cc (Voice::set_sync_source): Moved setting of
|
||||||
|
sync source from constructor.
|
||||||
|
|
||||||
|
* wave.h, wave.cc (WaveformGenerator::set_sync_source): Moved
|
||||||
|
setting of sync source from constructor.
|
||||||
|
|
||||||
|
2000-11-22 Dag Lem <resid@nimrod.no>
|
||||||
|
|
||||||
|
* Version 0.10 released.
|
||||||
|
|
||||||
|
* configure.in, Makefile.am: Use libtool to build library. The
|
||||||
|
hack to "disable" install is removed.
|
||||||
|
|
||||||
|
* extfilt.h, filter.h: Moved filter stability code from sid.cc.
|
||||||
|
|
||||||
|
* sid.cc (SID::clock): Moved filter stability code to
|
||||||
|
extfilt.h/filter.h. Don't clock the rest of the chip more
|
||||||
|
frequently than necessary.
|
||||||
|
|
||||||
|
* wave.cc: Typecast for pedantic (and probably incorrect)
|
||||||
|
compilers.
|
||||||
|
|
||||||
|
2000-05-18 Dag Lem <resid@nimrod.no>
|
||||||
|
|
||||||
|
* Version 0.9 released.
|
||||||
|
|
||||||
|
* filter.h (Filter::output): The sum of the filter outputs is no
|
||||||
|
longer weighted.
|
||||||
|
|
||||||
|
1999-06-24 Dag Lem <resid@nimrod.no>
|
||||||
|
|
||||||
|
* Version 0.8 released.
|
||||||
|
|
||||||
|
* filter.h, filter.cc, wave.h, wave.cc: Typecasts for pedantic
|
||||||
|
compilers.
|
||||||
|
|
||||||
|
* filter.h (Filter::clock): Voice 3 is only silenced by voice3off
|
||||||
|
if it is not routed through the filter.
|
||||||
|
|
||||||
|
* sid.cc (SID::State): Added constructor for proper initalization.
|
||||||
|
|
||||||
|
* spline.h: Inlined template functions to avoid problems at link
|
||||||
|
time with certain compilers.
|
||||||
|
|
||||||
|
1999-02-25 Dag Lem <resid@nimrod.no>
|
||||||
|
|
||||||
|
* Version 0.7 released.
|
||||||
|
|
||||||
|
* configure.in: Check whether compiler supports bool.
|
||||||
|
|
||||||
|
* extfilt.h, extfilt.cc: Implementation of C64 filter, external to
|
||||||
|
the SID chip.
|
||||||
|
|
||||||
|
* filter.h (Filter::clock): Optimized filter routing using a switch.
|
||||||
|
(Filter::output): Optimized filter mixing using a switch, avoiding
|
||||||
|
integer division. Corrected sign of filtered output, which is
|
||||||
|
inverted compared to unfiltered output.
|
||||||
|
|
||||||
|
* filter.cc (Filter::set_w0): Removed use of M_PI and math.h
|
||||||
|
functions. Use spline table to map fc to w0.
|
||||||
|
(Filter::fc_default): Return array of FC spline interpolation points.
|
||||||
|
(Filter::fc_plotter): Return FC spline plotter object.
|
||||||
|
|
||||||
|
* sid.h (SID::enable_external_filter): Enable/disable external
|
||||||
|
filter.
|
||||||
|
(SID::fc_default): Return array of FC spline interpolation points.
|
||||||
|
(SID::fc_plotter): Return FC spline plotter object.
|
||||||
|
(SID::State, SID::read_state, SID::write_state): Read and write
|
||||||
|
complete SID state.
|
||||||
|
|
||||||
|
* sid.cc (SID::clock): Age bus value. Clock external filter.
|
||||||
|
(SID::enable_external_filter): Enable/disable external filter.
|
||||||
|
|
||||||
|
* spline.h: Spline implementation. Used to specify mapping from
|
||||||
|
the FC register to filter cutoff frequency.
|
||||||
|
|
||||||
|
1998-11-14 Dag Lem <resid@nimrod.no>
|
||||||
|
|
||||||
|
* Version 0.6 released.
|
||||||
|
|
||||||
|
* configure.in: Allow compilation in a separate directory.
|
||||||
|
|
||||||
|
* wave.h (WaveformGenerator::synchronize): Handle special case when a
|
||||||
|
sync source is synced itself on the same cycle as its MSB is set
|
||||||
|
high.
|
||||||
|
|
||||||
|
* sid.cc (SID::clock): Only clock on MSB on/off for hard sync.
|
||||||
|
|
||||||
|
1998-09-06 Dag Lem <resid@nimrod.no>
|
||||||
|
|
||||||
|
* Version 0.5 released.
|
||||||
|
|
||||||
|
* version.cc (resid_version_string): Version string with C linkage.
|
||||||
|
|
||||||
|
* wave.cc (WaveformGenerator::set_chip_model): Emulation of MOS8580
|
||||||
|
combined waveforms.
|
||||||
|
|
||||||
|
1998-08-28 Dag Lem <resid@nimrod.no>
|
||||||
|
|
||||||
|
* Version 0.4 released.
|
||||||
|
|
||||||
|
* envelope.h (EnvelopeGenerator::clock): Count up to rate_period twice
|
||||||
|
during ADSR delay bug, and add one extra rate counter step.
|
||||||
|
|
||||||
|
* filter.cc (Filter::bsd_copysign): Renamed copysign function for
|
||||||
|
compilation on platforms where copysign is implemented as a macro.
|
||||||
|
|
||||||
|
1998-08-23 Dag Lem <resid@nimrod.no>
|
||||||
|
|
||||||
|
* Version 0.3 released.
|
||||||
|
|
||||||
|
* envelope.h (EnvelopeGenerator::clock): Handle ADSR boundary bug.
|
||||||
|
|
||||||
|
* envelope.cc (EnvelopeGenerator::rate_counter_period,
|
||||||
|
EnvelopeGenerator::exponential_counter_period): Corrected counter
|
||||||
|
periods.
|
||||||
|
|
||||||
|
* filter.h (Filter::clock): Optimized for speed (division by shifting).
|
||||||
|
|
||||||
|
* sid.h (SID::clock): New one-cycle optimized overload of the clock()
|
||||||
|
function.
|
||||||
|
|
||||||
|
* wave.h (WaveformGenerator::output_P_T): Combined waveform
|
||||||
|
pulse+triangle indexing corrected.
|
||||||
|
(WaveformGenerator::output_P__): Check for test bit to handle
|
||||||
|
pulse+test bit samples.
|
||||||
|
(WaveformGenerator::output): Optimized for speed (inlining).
|
||||||
|
|
||||||
|
1998-07-28 Dag Lem <resid@nimrod.no>
|
||||||
|
|
||||||
|
* Version 0.2 released.
|
||||||
|
|
||||||
|
* envelope.h (EnvelopeGenerator::clock): Start decay cycle immediately
|
||||||
|
at envelope counter 0xff. New sustain value is zero if the sustain
|
||||||
|
level is raised above the current envelope counter value.
|
||||||
|
(EnvelopeGenerator::step_envelope): Handle ADSR delay bug.
|
||||||
|
|
||||||
|
* envelope.cc (EnvelopeGenerator::rate_counter_period,
|
||||||
|
EnvelopeGenerator::exponential_counter_period): Corrected counter
|
||||||
|
periods.
|
||||||
|
(EnvelopeGenerator::writeCONTROL_REG): Do not modify rate counter.
|
||||||
|
|
||||||
|
* filter.cc (Filter::set_Q): Constrain Q to keep filter stable.
|
||||||
|
|
||||||
|
* sid.h (SID::read, SID::write, SID::bypass_filter): Simplified API
|
||||||
|
routing register access through the SID class.
|
||||||
|
|
||||||
|
* sid.cc (SID::output): Corrected variable-bit audio output return.
|
||||||
|
(SID::read, SID::write): Allow read of write only registers.
|
||||||
|
|
||||||
|
1998-06-09 Dag Lem <resid@nimrod.no>
|
||||||
|
|
||||||
|
* Version 0.1 released.
|
|
@ -0,0 +1,41 @@
|
||||||
|
/* addr, off, rle, values */
|
||||||
|
/*$0003*/ 0x83, 0x04, 0xaa, 0xb1, 0x91, 0xb3, 0x22,
|
||||||
|
/*$000b*/ 0x03, 0x4c,
|
||||||
|
/*$000f*/ 0x03, 0x04,
|
||||||
|
/*$0016*/ 0x86, 0x05, 0x19, 0x16, 0x00, 0x0a, 0x76, 0xa3,
|
||||||
|
/*$0022*/ 0x86, 0x03, 0x40, 0xa3, 0xb3, 0xbd,
|
||||||
|
/*$002b*/ 0x85, 0x01, 0x01, 0x08,
|
||||||
|
/*$0034*/ 0x07, 0xa0,
|
||||||
|
/*$0038*/ 0x03, 0xa0,
|
||||||
|
/*$003a*/ 0x01, 0xff,
|
||||||
|
/*$0042*/ 0x07, 0x08,
|
||||||
|
/*$0047*/ 0x04, 0x24,
|
||||||
|
/*$0053*/ 0x8b, 0x01, 0x03, 0x4c,
|
||||||
|
/*$0061*/ 0x0c, 0x8d,
|
||||||
|
/*$0063*/ 0x02, 0x10,
|
||||||
|
/*$0069*/ 0x84, 0x02, 0x8c, 0xff, 0xa0,
|
||||||
|
/*$0071*/ 0x85, 0x1e, 0x0a, 0xa3, 0xe6, 0x7a, 0xd0, 0x02, 0xe6, 0x7b, 0xad, 0x00, 0x08, 0xc9, 0x3a, 0xb0, 0x0a, 0xc9, 0x20, 0xf0, 0xef, 0x38, 0xe9, 0x30, 0x38, 0xe9, 0xd0, 0x60, 0x80, 0x4f, 0xc7, 0x52, 0x58,
|
||||||
|
/*$0091*/ 0x01, 0xff,
|
||||||
|
/*$009a*/ 0x08, 0x03,
|
||||||
|
/*$00b2*/ 0x97, 0x01, 0x3c, 0x03,
|
||||||
|
/*$00c2*/ 0x8e, 0x03, 0xa0, 0x30, 0xfd, 0x01,
|
||||||
|
/*$00c8*/ 0x82, 0x82, 0x03,
|
||||||
|
/*$00cb*/ 0x80, 0x81, 0x01,
|
||||||
|
/*$00ce*/ 0x01, 0x20,
|
||||||
|
/*$00d1*/ 0x82, 0x01, 0x18, 0x05,
|
||||||
|
/*$00d5*/ 0x82, 0x02, 0x27, 0x07, 0x0d,
|
||||||
|
/*$00d9*/ 0x81, 0x86, 0x84,
|
||||||
|
/*$00e0*/ 0x80, 0x85, 0x85,
|
||||||
|
/*$00e6*/ 0x80, 0x86, 0x86,
|
||||||
|
/*$00ed*/ 0x80, 0x85, 0x87,
|
||||||
|
/*$00f3*/ 0x80, 0x03, 0x18, 0xd9, 0x81, 0xeb,
|
||||||
|
/*$0176*/ 0x7f, 0x00,
|
||||||
|
/*$01f6*/ 0x7f, 0x00,
|
||||||
|
/*$0276*/ 0x7f, 0x00,
|
||||||
|
/*$0282*/ 0x8b, 0x0a, 0x08, 0x00, 0xa0, 0x00, 0x0e, 0x00, 0x04, 0x0a, 0x00, 0x04, 0x10,
|
||||||
|
/*$028f*/ 0x82, 0x01, 0x48, 0xeb,
|
||||||
|
/*$0300*/ 0xef, 0x0b, 0x8b, 0xe3, 0x83, 0xa4, 0x7c, 0xa5, 0x1a, 0xa7, 0xe4, 0xa7, 0x86, 0xae,
|
||||||
|
/*$0310*/ 0x84, 0x02, 0x4c, 0x48, 0xb2,
|
||||||
|
/*$0314*/ 0x81, 0x1f, 0x31, 0xea, 0x66, 0xfe, 0x47, 0xfe, 0x4a, 0xf3, 0x91, 0xf2, 0x0e, 0xf2, 0x50, 0xf2, 0x33, 0xf3, 0x57, 0xf1, 0xca, 0xf1, 0xed, 0xf6, 0x3e, 0xf1, 0x2f, 0xf3, 0x66, 0xfe, 0xa5, 0xf4, 0xed, 0xf5,
|
||||||
|
|
||||||
|
/*Total 217*/
|
Binary file not shown.
|
@ -0,0 +1,127 @@
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// This file is part of reSID, a MOS6581 SID emulator engine.
|
||||||
|
// Copyright (C) 2004 Dag Lem <resid@nimrod.no>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define RESID_VOICE_CC
|
||||||
|
|
||||||
|
#include "voice.h"
|
||||||
|
|
||||||
|
namespace reSID
|
||||||
|
{
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Constructor.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
Voice::Voice()
|
||||||
|
{
|
||||||
|
set_chip_model(MOS6581);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Set chip model.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void Voice::set_chip_model(chip_model model)
|
||||||
|
{
|
||||||
|
wave.set_chip_model(model);
|
||||||
|
envelope.set_chip_model(model);
|
||||||
|
|
||||||
|
if (model == MOS6581) {
|
||||||
|
// The waveform D/A converter introduces a DC offset in the signal
|
||||||
|
// to the envelope multiplying D/A converter. The "zero" level of
|
||||||
|
// the waveform D/A converter can be found as follows:
|
||||||
|
//
|
||||||
|
// Measure the "zero" voltage of voice 3 on the SID audio output
|
||||||
|
// pin, routing only voice 3 to the mixer ($d417 = $0b, $d418 =
|
||||||
|
// $0f, all other registers zeroed).
|
||||||
|
//
|
||||||
|
// Then set the sustain level for voice 3 to maximum and search for
|
||||||
|
// the waveform output value yielding the same voltage as found
|
||||||
|
// above. This is done by trying out different waveform output
|
||||||
|
// values until the correct value is found, e.g. with the following
|
||||||
|
// program:
|
||||||
|
//
|
||||||
|
// lda #$08
|
||||||
|
// sta $d412
|
||||||
|
// lda #$0b
|
||||||
|
// sta $d417
|
||||||
|
// lda #$0f
|
||||||
|
// sta $d418
|
||||||
|
// lda #$f0
|
||||||
|
// sta $d414
|
||||||
|
// lda #$21
|
||||||
|
// sta $d412
|
||||||
|
// lda #$01
|
||||||
|
// sta $d40e
|
||||||
|
//
|
||||||
|
// ldx #$00
|
||||||
|
// lda #$38 ; Tweak this to find the "zero" level
|
||||||
|
//l cmp $d41b
|
||||||
|
// bne l
|
||||||
|
// stx $d40e ; Stop frequency counter - freeze waveform output
|
||||||
|
// brk
|
||||||
|
//
|
||||||
|
// The waveform output range is 0x000 to 0xfff, so the "zero"
|
||||||
|
// level should ideally have been 0x800. In the measured chip, the
|
||||||
|
// waveform output "zero" level was found to be 0x380 (i.e. $d41b
|
||||||
|
// = 0x38) at an audio output voltage of 5.94V.
|
||||||
|
//
|
||||||
|
// With knowledge of the mixer op-amp characteristics, further estimates
|
||||||
|
// of waveform voltages can be obtained by sampling the EXT IN pin.
|
||||||
|
// From EXT IN samples, the corresponding waveform output can be found by
|
||||||
|
// using the model for the mixer.
|
||||||
|
//
|
||||||
|
// Such measurements have been done on a chip marked MOS 6581R4AR
|
||||||
|
// 0687 14, and the following results have been obtained:
|
||||||
|
// * The full range of one voice is approximately 1.5V.
|
||||||
|
// * The "zero" level rides at approximately 5.0V.
|
||||||
|
//
|
||||||
|
wave_zero = 0x380;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// No DC offsets in the MOS8580.
|
||||||
|
wave_zero = 0x800;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Set sync source.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void Voice::set_sync_source(Voice* source)
|
||||||
|
{
|
||||||
|
wave.set_sync_source(&source->wave);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Register functions.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void Voice::writeCONTROL_REG(reg8 control)
|
||||||
|
{
|
||||||
|
wave.writeCONTROL_REG(control);
|
||||||
|
envelope.writeCONTROL_REG(control);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// SID reset.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void Voice::reset()
|
||||||
|
{
|
||||||
|
wave.reset();
|
||||||
|
envelope.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace reSID
|
Binary file not shown.
|
@ -0,0 +1,84 @@
|
||||||
|
# Test for std c++11 compiler support
|
||||||
|
#
|
||||||
|
# trimmed down verision of AX_CXX_COMPILE_STDCXX_11
|
||||||
|
# from the GNU Autoconf Archive
|
||||||
|
#
|
||||||
|
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
|
||||||
|
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
|
||||||
|
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
|
||||||
|
# Copyright (c) 2014 Alexey Sokolov <sokolov@google.com>
|
||||||
|
#
|
||||||
|
# Copying and distribution of this file, with or without modification, are
|
||||||
|
# permitted in any medium without royalty provided the copyright notice
|
||||||
|
# and this notice are preserved. This file is offered as-is, without any
|
||||||
|
# warranty.
|
||||||
|
|
||||||
|
m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[
|
||||||
|
template <typename T>
|
||||||
|
struct check
|
||||||
|
{
|
||||||
|
static_assert(sizeof(int) <= sizeof(T), "not big enough");
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Base {
|
||||||
|
virtual void f() {}
|
||||||
|
};
|
||||||
|
struct Child : public Base {
|
||||||
|
virtual void f() override {}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef check<check<bool>> right_angle_brackets;
|
||||||
|
|
||||||
|
int a;
|
||||||
|
decltype(a) b;
|
||||||
|
|
||||||
|
typedef check<int> check_type;
|
||||||
|
check_type c;
|
||||||
|
check_type&& cr = static_cast<check_type&&>(c);
|
||||||
|
|
||||||
|
auto d = a;
|
||||||
|
auto l = [](){};
|
||||||
|
]])
|
||||||
|
|
||||||
|
AC_DEFUN([SID_CXX_COMPILE_STDCXX_11], [dnl
|
||||||
|
AC_LANG_PUSH([C++])dnl
|
||||||
|
ac_success=no
|
||||||
|
AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
|
||||||
|
ax_cv_cxx_compile_cxx11,
|
||||||
|
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
|
||||||
|
[ax_cv_cxx_compile_cxx11=yes],
|
||||||
|
[ax_cv_cxx_compile_cxx11=no])])
|
||||||
|
if test x$ax_cv_cxx_compile_cxx11 = xyes; then
|
||||||
|
ac_success=yes
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$ac_success = xno; then
|
||||||
|
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_-std=c++11])
|
||||||
|
AC_CACHE_CHECK(whether $CXX supports C++11 features with -std=c++11,
|
||||||
|
$cachevar,
|
||||||
|
[ac_save_CXXFLAGS="$CXXFLAGS"
|
||||||
|
CXXFLAGS="$CXXFLAGS -std=c++11"
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
|
||||||
|
[eval $cachevar=yes],
|
||||||
|
[eval $cachevar=no])
|
||||||
|
CXXFLAGS="$ac_save_CXXFLAGS"])
|
||||||
|
if eval test x\$$cachevar = xyes; then
|
||||||
|
CXXFLAGS="$CXXFLAGS -std=c++11"
|
||||||
|
ac_success=yes
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_LANG_POP([C++])
|
||||||
|
|
||||||
|
if test x$ac_success = xno; then
|
||||||
|
HAVE_CXX11=0
|
||||||
|
AC_MSG_NOTICE([No compiler with C++11 support was found])
|
||||||
|
else
|
||||||
|
HAVE_CXX11=1
|
||||||
|
AC_DEFINE(HAVE_CXX11,1,
|
||||||
|
[define if the compiler supports basic C++11 syntax])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(HAVE_CXX11)
|
||||||
|
])
|
|
@ -0,0 +1,256 @@
|
||||||
|
0 319
|
||||||
|
8 322
|
||||||
|
16 315
|
||||||
|
24 302
|
||||||
|
32 309
|
||||||
|
40 315
|
||||||
|
48 310
|
||||||
|
56 309
|
||||||
|
64 309
|
||||||
|
72 314
|
||||||
|
80 317
|
||||||
|
88 302
|
||||||
|
96 290
|
||||||
|
104 298
|
||||||
|
112 303
|
||||||
|
120 293
|
||||||
|
128 301
|
||||||
|
136 306
|
||||||
|
144 303
|
||||||
|
152 299
|
||||||
|
160 300
|
||||||
|
168 298
|
||||||
|
176 302
|
||||||
|
184 298
|
||||||
|
192 300
|
||||||
|
200 308
|
||||||
|
208 293
|
||||||
|
216 298
|
||||||
|
224 296
|
||||||
|
232 297
|
||||||
|
240 307
|
||||||
|
248 293
|
||||||
|
256 293
|
||||||
|
264 291
|
||||||
|
272 295
|
||||||
|
280 300
|
||||||
|
288 296
|
||||||
|
296 292
|
||||||
|
304 299
|
||||||
|
312 288
|
||||||
|
320 287
|
||||||
|
328 299
|
||||||
|
336 305
|
||||||
|
344 302
|
||||||
|
352 294
|
||||||
|
360 295
|
||||||
|
368 290
|
||||||
|
376 290
|
||||||
|
384 294
|
||||||
|
392 297
|
||||||
|
400 280
|
||||||
|
408 288
|
||||||
|
416 302
|
||||||
|
424 306
|
||||||
|
432 301
|
||||||
|
440 291
|
||||||
|
448 296
|
||||||
|
456 301
|
||||||
|
464 303
|
||||||
|
472 290
|
||||||
|
480 307
|
||||||
|
488 294
|
||||||
|
496 302
|
||||||
|
504 302
|
||||||
|
512 299
|
||||||
|
520 297
|
||||||
|
528 300
|
||||||
|
536 292
|
||||||
|
544 300
|
||||||
|
552 295
|
||||||
|
560 299
|
||||||
|
568 291
|
||||||
|
576 306
|
||||||
|
584 308
|
||||||
|
592 308
|
||||||
|
600 313
|
||||||
|
608 309
|
||||||
|
616 303
|
||||||
|
624 307
|
||||||
|
632 308
|
||||||
|
640 309
|
||||||
|
648 307
|
||||||
|
656 305
|
||||||
|
664 316
|
||||||
|
672 308
|
||||||
|
680 303
|
||||||
|
688 323
|
||||||
|
696 309
|
||||||
|
704 307
|
||||||
|
712 318
|
||||||
|
720 312
|
||||||
|
728 326
|
||||||
|
736 327
|
||||||
|
744 325
|
||||||
|
752 332
|
||||||
|
760 346
|
||||||
|
768 328
|
||||||
|
776 327
|
||||||
|
784 339
|
||||||
|
792 344
|
||||||
|
800 340
|
||||||
|
808 347
|
||||||
|
816 339
|
||||||
|
824 349
|
||||||
|
832 343
|
||||||
|
840 349
|
||||||
|
848 360
|
||||||
|
856 357
|
||||||
|
864 361
|
||||||
|
872 363
|
||||||
|
880 368
|
||||||
|
888 363
|
||||||
|
896 369
|
||||||
|
904 373
|
||||||
|
912 370
|
||||||
|
920 382
|
||||||
|
928 384
|
||||||
|
936 391
|
||||||
|
944 392
|
||||||
|
952 415
|
||||||
|
960 409
|
||||||
|
968 408
|
||||||
|
976 431
|
||||||
|
984 441
|
||||||
|
992 438
|
||||||
|
1000 444
|
||||||
|
1008 461
|
||||||
|
1016 474
|
||||||
|
1024 398
|
||||||
|
1032 414
|
||||||
|
1040 430
|
||||||
|
1048 429
|
||||||
|
1056 435
|
||||||
|
1064 445
|
||||||
|
1072 444
|
||||||
|
1080 452
|
||||||
|
1088 449
|
||||||
|
1096 464
|
||||||
|
1104 472
|
||||||
|
1112 480
|
||||||
|
1120 479
|
||||||
|
1128 490
|
||||||
|
1136 492
|
||||||
|
1144 527
|
||||||
|
1152 521
|
||||||
|
1160 520
|
||||||
|
1168 549
|
||||||
|
1176 556
|
||||||
|
1184 563
|
||||||
|
1192 553
|
||||||
|
1200 588
|
||||||
|
1208 590
|
||||||
|
1216 600
|
||||||
|
1224 607
|
||||||
|
1232 622
|
||||||
|
1240 650
|
||||||
|
1248 670
|
||||||
|
1256 673
|
||||||
|
1264 689
|
||||||
|
1272 713
|
||||||
|
1280 693
|
||||||
|
1288 692
|
||||||
|
1296 716
|
||||||
|
1304 741
|
||||||
|
1312 766
|
||||||
|
1320 763
|
||||||
|
1328 789
|
||||||
|
1336 822
|
||||||
|
1344 810
|
||||||
|
1352 835
|
||||||
|
1360 868
|
||||||
|
1368 901
|
||||||
|
1376 911
|
||||||
|
1384 961
|
||||||
|
1392 989
|
||||||
|
1400 1028
|
||||||
|
1408 1035
|
||||||
|
1416 1081
|
||||||
|
1424 1116
|
||||||
|
1432 1153
|
||||||
|
1440 1199
|
||||||
|
1448 1263
|
||||||
|
1456 1353
|
||||||
|
1464 1401
|
||||||
|
1472 1422
|
||||||
|
1480 1477
|
||||||
|
1488 1603
|
||||||
|
1496 1633
|
||||||
|
1504 1718
|
||||||
|
1512 1815
|
||||||
|
1520 1878
|
||||||
|
1528 2065
|
||||||
|
1536 1725
|
||||||
|
1544 1791
|
||||||
|
1552 1850
|
||||||
|
1560 1956
|
||||||
|
1568 2040
|
||||||
|
1576 2141
|
||||||
|
1584 2249
|
||||||
|
1592 2396
|
||||||
|
1600 2459
|
||||||
|
1608 2563
|
||||||
|
1616 2683
|
||||||
|
1624 2842
|
||||||
|
1632 2973
|
||||||
|
1640 3133
|
||||||
|
1648 3276
|
||||||
|
1656 3459
|
||||||
|
1664 3425
|
||||||
|
1672 3585
|
||||||
|
1680 3714
|
||||||
|
1688 3906
|
||||||
|
1696 4011
|
||||||
|
1704 4194
|
||||||
|
1712 4366
|
||||||
|
1720 4616
|
||||||
|
1728 4735
|
||||||
|
1736 5003
|
||||||
|
1744 5209
|
||||||
|
1752 5439
|
||||||
|
1760 5619
|
||||||
|
1768 5848
|
||||||
|
1776 6111
|
||||||
|
1784 6405
|
||||||
|
1792 6121
|
||||||
|
1800 6343
|
||||||
|
1808 6597
|
||||||
|
1816 6795
|
||||||
|
1824 7033
|
||||||
|
1832 7312
|
||||||
|
1840 7499
|
||||||
|
1848 7816
|
||||||
|
1856 7961
|
||||||
|
1864 8181
|
||||||
|
1872 8463
|
||||||
|
1880 8671
|
||||||
|
1888 8988
|
||||||
|
1896 9251
|
||||||
|
1904 9593
|
||||||
|
1912 9950
|
||||||
|
1920 9990
|
||||||
|
1928 10290
|
||||||
|
1936 10590
|
||||||
|
1944 10910
|
||||||
|
1952 11173
|
||||||
|
1960 11465
|
||||||
|
1968 11770
|
||||||
|
1976 12103
|
||||||
|
1984 12272
|
||||||
|
1992 12635
|
||||||
|
2000 13012
|
||||||
|
2008 13357
|
||||||
|
2016 13614
|
||||||
|
2024 13973
|
||||||
|
2032 14315
|
||||||
|
2040 14871
|
|
@ -0,0 +1,256 @@
|
||||||
|
0 337
|
||||||
|
8 364
|
||||||
|
16 360
|
||||||
|
24 373
|
||||||
|
32 380
|
||||||
|
40 392
|
||||||
|
48 398
|
||||||
|
56 403
|
||||||
|
64 413
|
||||||
|
72 419
|
||||||
|
80 422
|
||||||
|
88 420
|
||||||
|
96 439
|
||||||
|
104 443
|
||||||
|
112 451
|
||||||
|
120 442
|
||||||
|
128 467
|
||||||
|
136 462
|
||||||
|
144 467
|
||||||
|
152 480
|
||||||
|
160 483
|
||||||
|
168 497
|
||||||
|
176 508
|
||||||
|
184 517
|
||||||
|
192 519
|
||||||
|
200 533
|
||||||
|
208 554
|
||||||
|
216 558
|
||||||
|
224 560
|
||||||
|
232 561
|
||||||
|
240 586
|
||||||
|
248 594
|
||||||
|
256 563
|
||||||
|
264 585
|
||||||
|
272 589
|
||||||
|
280 608
|
||||||
|
288 633
|
||||||
|
296 638
|
||||||
|
304 659
|
||||||
|
312 650
|
||||||
|
320 666
|
||||||
|
328 673
|
||||||
|
336 690
|
||||||
|
344 716
|
||||||
|
352 711
|
||||||
|
360 734
|
||||||
|
368 753
|
||||||
|
376 772
|
||||||
|
384 758
|
||||||
|
392 807
|
||||||
|
400 797
|
||||||
|
408 809
|
||||||
|
416 796
|
||||||
|
424 834
|
||||||
|
432 828
|
||||||
|
440 846
|
||||||
|
448 847
|
||||||
|
456 857
|
||||||
|
464 884
|
||||||
|
472 884
|
||||||
|
480 928
|
||||||
|
488 1006
|
||||||
|
496 1029
|
||||||
|
504 1061
|
||||||
|
512 1022
|
||||||
|
520 1012
|
||||||
|
528 1000
|
||||||
|
536 1044
|
||||||
|
544 1106
|
||||||
|
552 1111
|
||||||
|
560 1105
|
||||||
|
568 1140
|
||||||
|
576 1139
|
||||||
|
584 1177
|
||||||
|
592 1228
|
||||||
|
600 1303
|
||||||
|
608 1316
|
||||||
|
616 1410
|
||||||
|
624 1462
|
||||||
|
632 1565
|
||||||
|
640 1545
|
||||||
|
648 1627
|
||||||
|
656 1668
|
||||||
|
664 1723
|
||||||
|
672 1759
|
||||||
|
680 1796
|
||||||
|
688 1924
|
||||||
|
696 1948
|
||||||
|
704 2027
|
||||||
|
712 2089
|
||||||
|
720 2140
|
||||||
|
728 2229
|
||||||
|
736 2342
|
||||||
|
744 2435
|
||||||
|
752 2611
|
||||||
|
760 2716
|
||||||
|
768 2602
|
||||||
|
776 2735
|
||||||
|
784 2820
|
||||||
|
792 2946
|
||||||
|
800 3062
|
||||||
|
808 3169
|
||||||
|
816 3263
|
||||||
|
824 3391
|
||||||
|
832 3425
|
||||||
|
840 3574
|
||||||
|
848 3694
|
||||||
|
856 3814
|
||||||
|
864 3933
|
||||||
|
872 4019
|
||||||
|
880 4170
|
||||||
|
888 4292
|
||||||
|
896 4252
|
||||||
|
904 4396
|
||||||
|
912 4445
|
||||||
|
920 4586
|
||||||
|
928 4748
|
||||||
|
936 4866
|
||||||
|
944 4966
|
||||||
|
952 5171
|
||||||
|
960 5233
|
||||||
|
968 5310
|
||||||
|
976 5376
|
||||||
|
984 5544
|
||||||
|
992 5633
|
||||||
|
1000 5695
|
||||||
|
1008 5826
|
||||||
|
1016 5954
|
||||||
|
1024 5324
|
||||||
|
1032 5448
|
||||||
|
1040 5492
|
||||||
|
1048 5643
|
||||||
|
1056 5658
|
||||||
|
1064 5792
|
||||||
|
1072 5846
|
||||||
|
1080 5914
|
||||||
|
1088 5981
|
||||||
|
1096 6062
|
||||||
|
1104 6200
|
||||||
|
1112 6261
|
||||||
|
1120 6322
|
||||||
|
1128 6493
|
||||||
|
1136 6563
|
||||||
|
1144 6665
|
||||||
|
1152 6681
|
||||||
|
1160 6720
|
||||||
|
1168 6828
|
||||||
|
1176 6942
|
||||||
|
1184 7015
|
||||||
|
1192 7195
|
||||||
|
1200 7242
|
||||||
|
1208 7290
|
||||||
|
1216 7415
|
||||||
|
1224 7498
|
||||||
|
1232 7585
|
||||||
|
1240 7796
|
||||||
|
1248 7874
|
||||||
|
1256 8118
|
||||||
|
1264 8224
|
||||||
|
1272 8446
|
||||||
|
1280 8379
|
||||||
|
1288 8484
|
||||||
|
1296 8563
|
||||||
|
1304 8742
|
||||||
|
1312 8877
|
||||||
|
1320 9168
|
||||||
|
1328 9343
|
||||||
|
1336 9535
|
||||||
|
1344 9644
|
||||||
|
1352 9926
|
||||||
|
1360 10144
|
||||||
|
1368 10517
|
||||||
|
1376 10706
|
||||||
|
1384 11055
|
||||||
|
1392 11329
|
||||||
|
1400 11664
|
||||||
|
1408 11564
|
||||||
|
1416 11824
|
||||||
|
1424 12037
|
||||||
|
1432 12326
|
||||||
|
1440 12416
|
||||||
|
1448 12644
|
||||||
|
1456 12997
|
||||||
|
1464 13345
|
||||||
|
1472 13466
|
||||||
|
1480 13742
|
||||||
|
1488 14084
|
||||||
|
1496 14330
|
||||||
|
1504 14593
|
||||||
|
1512 14841
|
||||||
|
1520 15163
|
||||||
|
1528 15494
|
||||||
|
1536 14783
|
||||||
|
1544 15022
|
||||||
|
1552 15224
|
||||||
|
1560 15508
|
||||||
|
1568 15680
|
||||||
|
1576 15944
|
||||||
|
1584 16121
|
||||||
|
1592 16456
|
||||||
|
1600 16559
|
||||||
|
1608 16812
|
||||||
|
1616 17005
|
||||||
|
1624 17294
|
||||||
|
1632 17533
|
||||||
|
1640 17745
|
||||||
|
1648 17886
|
||||||
|
1656 18137
|
||||||
|
1664 18136
|
||||||
|
1672 18454
|
||||||
|
1680 18555
|
||||||
|
1688 18701
|
||||||
|
1696 19005
|
||||||
|
1704 19116
|
||||||
|
1712 19354
|
||||||
|
1720 19640
|
||||||
|
1728 19688
|
||||||
|
1736 19989
|
||||||
|
1744 20189
|
||||||
|
1752 20368
|
||||||
|
1760 20593
|
||||||
|
1768 20763
|
||||||
|
1776 20961
|
||||||
|
1784 21119
|
||||||
|
1792 21076
|
||||||
|
1800 21227
|
||||||
|
1808 21378
|
||||||
|
1816 21385
|
||||||
|
1824 21562
|
||||||
|
1832 21691
|
||||||
|
1840 21870
|
||||||
|
1848 21966
|
||||||
|
1856 21997
|
||||||
|
1864 22122
|
||||||
|
1872 22255
|
||||||
|
1880 22442
|
||||||
|
1888 22409
|
||||||
|
1896 22546
|
||||||
|
1904 22642
|
||||||
|
1912 22585
|
||||||
|
1920 22588
|
||||||
|
1928 22646
|
||||||
|
1936 22698
|
||||||
|
1944 22799
|
||||||
|
1952 22807
|
||||||
|
1960 22796
|
||||||
|
1968 22919
|
||||||
|
1976 22888
|
||||||
|
1984 23022
|
||||||
|
1992 22928
|
||||||
|
2000 22954
|
||||||
|
2008 22896
|
||||||
|
2016 23017
|
||||||
|
2024 22917
|
||||||
|
2032 22763
|
||||||
|
2040 23139
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,217 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2011-2014 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
* Copyright 2007-2010 Antti Lankila
|
||||||
|
* Copyright 2000 Simon White
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SIDTUNEBASE_H
|
||||||
|
#define SIDTUNEBASE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "sidplayfp/SidTuneInfo.h"
|
||||||
|
#include "sidplayfp/siddefs.h"
|
||||||
|
|
||||||
|
#include "SidTuneCfg.h"
|
||||||
|
#include "SmartPtr.h"
|
||||||
|
#include "SidTuneInfoImpl.h"
|
||||||
|
|
||||||
|
#include "sidcxx11.h"
|
||||||
|
|
||||||
|
class sidmemory;
|
||||||
|
template <class T> class SmartPtr_sidtt;
|
||||||
|
|
||||||
|
namespace libsidplayfp
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* loadError
|
||||||
|
*/
|
||||||
|
class loadError
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const char* m_msg;
|
||||||
|
public:
|
||||||
|
loadError(const char* msg) : m_msg(msg) {}
|
||||||
|
const char* message() const { return m_msg; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SidTuneBaseBase
|
||||||
|
*/
|
||||||
|
class SidTuneBase
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
typedef std::vector<uint_least8_t> buffer_t;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// Also PSID file format limit.
|
||||||
|
static const unsigned int MAX_SONGS = 256;
|
||||||
|
|
||||||
|
static const char ERR_NOT_ENOUGH_MEMORY[];
|
||||||
|
static const char ERR_TRUNCATED[];
|
||||||
|
static const char ERR_INVALID[];
|
||||||
|
|
||||||
|
public: // ----------------------------------------------------------------
|
||||||
|
virtual ~SidTuneBase() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a sidtune from a file.
|
||||||
|
*
|
||||||
|
* To retrieve data from standard input pass in filename "-".
|
||||||
|
* If you want to override the default filename extensions use this
|
||||||
|
* contructor. Please note, that if the specified "sidTuneFileName"
|
||||||
|
* does exist and the loader is able to determine its file format,
|
||||||
|
* this function does not try to append any file name extension.
|
||||||
|
* See "sidtune.cpp" for the default list of file name extensions.
|
||||||
|
*/
|
||||||
|
static SidTuneBase* load(const char* fileName, const char **fileNameExt, bool separatorIsSlash);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a single-file sidtune from a memory buffer.
|
||||||
|
* Currently supported: PSID format
|
||||||
|
*/
|
||||||
|
static SidTuneBase* read(const uint_least8_t* sourceBuffer, uint_least32_t bufferLen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select sub-song (0 = default starting song)
|
||||||
|
* and return active song number out of [1,2,..,SIDTUNE_MAX_SONGS].
|
||||||
|
*/
|
||||||
|
unsigned int selectSong(unsigned int songNum);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve sub-song specific information.
|
||||||
|
*/
|
||||||
|
const SidTuneInfo* getInfo() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select sub-song (0 = default starting song)
|
||||||
|
* and retrieve active song information.
|
||||||
|
*/
|
||||||
|
const SidTuneInfo* getInfo(unsigned int songNum);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy sidtune into C64 memory (64 KB).
|
||||||
|
*/
|
||||||
|
virtual bool placeSidTuneInC64mem(sidmemory* mem);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the MD5 hash of the tune.
|
||||||
|
* Not providing an md5 buffer will cause the internal one to be used.
|
||||||
|
* If provided, buffer must be MD5_LENGTH + 1
|
||||||
|
* @return a pointer to the buffer containing the md5 string.
|
||||||
|
*/
|
||||||
|
virtual const char *createMD5(char *) { return 0; }
|
||||||
|
|
||||||
|
protected: // -------------------------------------------------------------
|
||||||
|
|
||||||
|
std::unique_ptr<SidTuneInfoImpl> info;
|
||||||
|
|
||||||
|
uint_least8_t songSpeed[MAX_SONGS];
|
||||||
|
SidTuneInfo::clock_t clockSpeed[MAX_SONGS];
|
||||||
|
|
||||||
|
/// For files with header: offset to real data
|
||||||
|
uint_least32_t fileOffset;
|
||||||
|
|
||||||
|
buffer_t cache;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SidTuneBase();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does not affect status of object, and therefore can be used
|
||||||
|
* to load files. Error string is put into info.statusString, though.
|
||||||
|
*/
|
||||||
|
static void loadFile(const char* fileName,buffer_t& bufferRef);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert 32-bit PSID-style speed word to internal tables.
|
||||||
|
*/
|
||||||
|
void convertOldStyleSpeedToTables(uint_least32_t speed,
|
||||||
|
SidTuneInfo::clock_t clock = SidTuneInfo::CLOCK_PAL);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check compatibility details are sensible.
|
||||||
|
*/
|
||||||
|
bool checkCompatibility();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for valid relocation information.
|
||||||
|
*/
|
||||||
|
bool checkRelocInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common address resolution procedure.
|
||||||
|
*/
|
||||||
|
void resolveAddrs(const uint_least8_t* c64data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache the data of a single-file or two-file sidtune and its
|
||||||
|
* corresponding file names.
|
||||||
|
*
|
||||||
|
* @param dataFileName
|
||||||
|
* @param infoFileName
|
||||||
|
* @param buf
|
||||||
|
* @param isSlashedFileName If your opendir() and readdir()->d_name return path names
|
||||||
|
* that contain the forward slash (/) as file separator, but
|
||||||
|
* your operating system uses a different character, there are
|
||||||
|
* extra functions that can deal with this special case. Set
|
||||||
|
* separatorIsSlash to true if you like path names to be split
|
||||||
|
* correctly.
|
||||||
|
* You do not need these extra functions if your systems file
|
||||||
|
* separator is the forward slash.
|
||||||
|
*/
|
||||||
|
virtual void acceptSidTune(const char* dataFileName, const char* infoFileName,
|
||||||
|
buffer_t& buf, bool isSlashedFileName);
|
||||||
|
|
||||||
|
class PetsciiToAscii
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string buffer;
|
||||||
|
public:
|
||||||
|
const char* convert(SmartPtr_sidtt<const uint_least8_t>& spPet);
|
||||||
|
};
|
||||||
|
|
||||||
|
private: // ---------------------------------------------------------------
|
||||||
|
|
||||||
|
#if !defined(SIDTUNE_NO_STDIN_LOADER)
|
||||||
|
static SidTuneBase* getFromStdIn();
|
||||||
|
#endif
|
||||||
|
static SidTuneBase* getFromFiles(const char* name, const char **fileNameExtensions, bool separatorIsSlash);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to retrieve single-file sidtune from specified buffer.
|
||||||
|
*/
|
||||||
|
static SidTuneBase* getFromBuffer(const uint_least8_t* const buffer, uint_least32_t bufferLen);
|
||||||
|
|
||||||
|
static void createNewFileName(std::string& destString,
|
||||||
|
const char* sourceName, const char* sourceExt);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// prevent copying
|
||||||
|
SidTuneBase(const SidTuneBase&);
|
||||||
|
SidTuneBase& operator=(SidTuneBase&);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* SIDTUNEBASE_H */
|
|
@ -0,0 +1,458 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2011-2013 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
* Copyright 2007-2010 Antti Lankila
|
||||||
|
* Copyright 2004,2010 Dag Lem <resid@nimrod.no>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FILTER6581_H
|
||||||
|
#define FILTER6581_H
|
||||||
|
|
||||||
|
#include "siddefs-fp.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "Filter.h"
|
||||||
|
#include "FilterModelConfig.h"
|
||||||
|
|
||||||
|
namespace reSIDfp
|
||||||
|
{
|
||||||
|
|
||||||
|
class Integrator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The SID filter is modeled with a two-integrator-loop biquadratic filter,
|
||||||
|
* which has been confirmed by Bob Yannes to be the actual circuit used in
|
||||||
|
* the SID chip.
|
||||||
|
*
|
||||||
|
* Measurements show that excellent emulation of the SID filter is achieved,
|
||||||
|
* except when high resonance is combined with high sustain levels.
|
||||||
|
* In this case the SID op-amps are performing less than ideally and are
|
||||||
|
* causing some peculiar behavior of the SID filter. This however seems to
|
||||||
|
* have more effect on the overall amplitude than on the color of the sound.
|
||||||
|
*
|
||||||
|
* The theory for the filter circuit can be found in "Microelectric Circuits"
|
||||||
|
* by Adel S. Sedra and Kenneth C. Smith.
|
||||||
|
* The circuit is modeled based on the explanation found there except that
|
||||||
|
* an additional inverter is used in the feedback from the bandpass output,
|
||||||
|
* allowing the summer op-amp to operate in single-ended mode. This yields
|
||||||
|
* filter outputs with levels independent of Q, which corresponds with the
|
||||||
|
* results obtained from a real SID.
|
||||||
|
*
|
||||||
|
* We have been able to model the summer and the two integrators of the circuit
|
||||||
|
* to form components of an IIR filter.
|
||||||
|
* Vhp is the output of the summer, Vbp is the output of the first integrator,
|
||||||
|
* and Vlp is the output of the second integrator in the filter circuit.
|
||||||
|
*
|
||||||
|
* According to Bob Yannes, the active stages of the SID filter are not really
|
||||||
|
* op-amps. Rather, simple NMOS inverters are used. By biasing an inverter
|
||||||
|
* into its region of quasi-linear operation using a feedback resistor from
|
||||||
|
* input to output, a MOS inverter can be made to act like an op-amp for
|
||||||
|
* small signals centered around the switching threshold.
|
||||||
|
*
|
||||||
|
* In 2008, Michael Huth facilitated closer investigation of the SID 6581
|
||||||
|
* filter circuit by publishing high quality microscope photographs of the die.
|
||||||
|
* Tommi Lempinen has done an impressive work on re-vectorizing and annotating
|
||||||
|
* the die photographs, substantially simplifying further analysis of the
|
||||||
|
* filter circuit.
|
||||||
|
*
|
||||||
|
* The filter schematics below are reverse engineered from these re-vectorized
|
||||||
|
* and annotated die photographs. While the filter first depicted in reSID 0.9
|
||||||
|
* is a correct model of the basic filter, the schematics are now completed
|
||||||
|
* with the audio mixer and output stage, including details on intended
|
||||||
|
* relative resistor values. Also included are schematics for the NMOS FET
|
||||||
|
* voltage controlled resistors (VCRs) used to control cutoff frequency, the
|
||||||
|
* DAC which controls the VCRs, the NMOS op-amps, and the output buffer.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* SID filter / mixer / output
|
||||||
|
* ---------------------------
|
||||||
|
* ~~~
|
||||||
|
* ---------------------------------------------------
|
||||||
|
* | |
|
||||||
|
* | --1R1-- \-- D7 |
|
||||||
|
* | ---R1-- | | |
|
||||||
|
* | | | |--2R1-- \--| D6 |
|
||||||
|
* | ------------<A]-----| | $17 |
|
||||||
|
* | | |--4R1-- \--| D5 1=open | (3.5R1)
|
||||||
|
* | | | | |
|
||||||
|
* | | --8R1-- \--| D4 | (7.0R1)
|
||||||
|
* | | | |
|
||||||
|
* $17 | | (CAP2B) | (CAP1B) |
|
||||||
|
* 0=to mixer | --R8-- ---R8-- ---C---| ---C---|
|
||||||
|
* 1=to filter | | | | | | | |
|
||||||
|
* ------R8--|-----[A>--|--Rw-----[A>--|--Rw-----[A>--|
|
||||||
|
* ve (EXT IN) | | | |
|
||||||
|
* D3 \ ---------------R8--| | | (CAP2A) | (CAP1A)
|
||||||
|
* | v3 | | vhp | vbp | vlp
|
||||||
|
* D2 | \ -----------R8--| ----- | |
|
||||||
|
* | | v2 | | | |
|
||||||
|
* D1 | | \ -------R8--| | ---------------- |
|
||||||
|
* | | | v1 | | | |
|
||||||
|
* D0 | | | \ ---R8-- | | ---------------------------
|
||||||
|
* | | | | | | |
|
||||||
|
* R6 R6 R6 R6 R6 R6 R6
|
||||||
|
* | | | | $18 | | | $18
|
||||||
|
* | \ | | D7: 1=open \ \ \ D6 - D4: 0=open
|
||||||
|
* | | | | | | |
|
||||||
|
* --------------------------------- 12V
|
||||||
|
* |
|
||||||
|
* | D3 --/ --1R2-- |
|
||||||
|
* | ---R8-- | | ---R2-- |
|
||||||
|
* | | | D2 |--/ --2R2--| | | ||--
|
||||||
|
* ------[A>---------| |-----[A>-----||
|
||||||
|
* D1 |--/ --4R2--| (4.25R2) ||--
|
||||||
|
* $18 | | |
|
||||||
|
* 0=open D0 --/ --8R2-- (8.75R2) |
|
||||||
|
*
|
||||||
|
* vo (AUDIO
|
||||||
|
* OUT)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* v1 - voice 1
|
||||||
|
* v2 - voice 2
|
||||||
|
* v3 - voice 3
|
||||||
|
* ve - ext in
|
||||||
|
* vhp - highpass output
|
||||||
|
* vbp - bandpass output
|
||||||
|
* vlp - lowpass output
|
||||||
|
* vo - audio out
|
||||||
|
* [A> - single ended inverting op-amp (self-biased NMOS inverter)
|
||||||
|
* Rn - "resistors", implemented with custom NMOS FETs
|
||||||
|
* Rw - cutoff frequency resistor (VCR)
|
||||||
|
* C - capacitor
|
||||||
|
* ~~~
|
||||||
|
* Notes:
|
||||||
|
*
|
||||||
|
* R2 ~ 2.0*R1
|
||||||
|
* R6 ~ 6.0*R1
|
||||||
|
* R8 ~ 8.0*R1
|
||||||
|
* R24 ~ 24.0*R1
|
||||||
|
*
|
||||||
|
* The Rn "resistors" in the circuit are implemented with custom NMOS FETs,
|
||||||
|
* probably because of space constraints on the SID die. The silicon substrate
|
||||||
|
* is laid out in a narrow strip or "snake", with a strip length proportional
|
||||||
|
* to the intended resistance. The polysilicon gate electrode covers the entire
|
||||||
|
* silicon substrate and is fixed at 12V in order for the NMOS FET to operate
|
||||||
|
* in triode mode (a.k.a. linear mode or ohmic mode).
|
||||||
|
*
|
||||||
|
* Even in "linear mode", an NMOS FET is only an approximation of a resistor,
|
||||||
|
* as the apparant resistance increases with increasing drain-to-source
|
||||||
|
* voltage. If the drain-to-source voltage should approach the gate voltage
|
||||||
|
* of 12V, the NMOS FET will enter saturation mode (a.k.a. active mode), and
|
||||||
|
* the NMOS FET will not operate anywhere like a resistor.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NMOS FET voltage controlled resistor (VCR)
|
||||||
|
* ------------------------------------------
|
||||||
|
* ~~~
|
||||||
|
* Vw
|
||||||
|
*
|
||||||
|
* |
|
||||||
|
* |
|
||||||
|
* R1
|
||||||
|
* |
|
||||||
|
* --R1--|
|
||||||
|
* | __|__
|
||||||
|
* | -----
|
||||||
|
* | | |
|
||||||
|
* vi ---------- -------- vo
|
||||||
|
* | |
|
||||||
|
* ----R24----
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* vi - input
|
||||||
|
* vo - output
|
||||||
|
* Rn - "resistors", implemented with custom NMOS FETs
|
||||||
|
* Vw - voltage from 11-bit DAC (frequency cutoff control)
|
||||||
|
* ~~~
|
||||||
|
* Notes:
|
||||||
|
*
|
||||||
|
* An approximate value for R24 can be found by using the formula for the
|
||||||
|
* filter cutoff frequency:
|
||||||
|
*
|
||||||
|
* FCmin = 1/(2*pi*Rmax*C)
|
||||||
|
*
|
||||||
|
* Assuming that a the setting for minimum cutoff frequency in combination with
|
||||||
|
* a low level input signal ensures that only negligible current will flow
|
||||||
|
* through the transistor in the schematics above, values for FCmin and C can
|
||||||
|
* be substituted in this formula to find Rmax.
|
||||||
|
* Using C = 470pF and FCmin = 220Hz (measured value), we get:
|
||||||
|
*
|
||||||
|
* FCmin = 1/(2*pi*Rmax*C)
|
||||||
|
* Rmax = 1/(2*pi*FCmin*C) = 1/(2*pi*220*470e-12) ~ 1.5MOhm
|
||||||
|
*
|
||||||
|
* From this it follows that:
|
||||||
|
* R24 = Rmax ~ 1.5MOhm
|
||||||
|
* R1 ~ R24/24 ~ 64kOhm
|
||||||
|
* R2 ~ 2.0*R1 ~ 128kOhm
|
||||||
|
* R6 ~ 6.0*R1 ~ 384kOhm
|
||||||
|
* R8 ~ 8.0*R1 ~ 512kOhm
|
||||||
|
*
|
||||||
|
* Note that these are only approximate values for one particular SID chip,
|
||||||
|
* due to process variations the values can be substantially different in
|
||||||
|
* other chips.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Filter frequency cutoff DAC
|
||||||
|
* ---------------------------
|
||||||
|
*
|
||||||
|
* ~~~
|
||||||
|
* 12V 10 9 8 7 6 5 4 3 2 1 0 VGND
|
||||||
|
* | | | | | | | | | | | | | Missing
|
||||||
|
* 2R 2R 2R 2R 2R 2R 2R 2R 2R 2R 2R 2R 2R termination
|
||||||
|
* | | | | | | | | | | | | |
|
||||||
|
* Vw ----R---R---R---R---R---R---R---R---R---R---R-- ---
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Bit on: 12V
|
||||||
|
* Bit off: 5V (VGND)
|
||||||
|
* ~~~
|
||||||
|
* As is the case with all MOS 6581 DACs, the termination to (virtual) ground
|
||||||
|
* at bit 0 is missing.
|
||||||
|
*
|
||||||
|
* Furthermore, the control of the two VCRs imposes a load on the DAC output
|
||||||
|
* which varies with the input signals to the VCRs. This can be seen from the
|
||||||
|
* VCR figure above.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* "Op-amp" (self-biased NMOS inverter)
|
||||||
|
* ------------------------------------
|
||||||
|
* ~~~
|
||||||
|
*
|
||||||
|
* 12V
|
||||||
|
*
|
||||||
|
* |
|
||||||
|
* -----------|
|
||||||
|
* | |
|
||||||
|
* | ------|
|
||||||
|
* | | |
|
||||||
|
* | | ||--
|
||||||
|
* | --||
|
||||||
|
* | ||--
|
||||||
|
* ||-- |
|
||||||
|
* vi -----|| |--------- vo
|
||||||
|
* ||-- | |
|
||||||
|
* | ||-- |
|
||||||
|
* |-------|| |
|
||||||
|
* | ||-- |
|
||||||
|
* ||-- | |
|
||||||
|
* --|| | |
|
||||||
|
* | ||-- | |
|
||||||
|
* | | | |
|
||||||
|
* | -----------| |
|
||||||
|
* | | |
|
||||||
|
* | |
|
||||||
|
* | GND |
|
||||||
|
* | |
|
||||||
|
* ----------------------
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* vi - input
|
||||||
|
* vo - output
|
||||||
|
* ~~~
|
||||||
|
* Notes:
|
||||||
|
*
|
||||||
|
* The schematics above are laid out to show that the "op-amp" logically
|
||||||
|
* consists of two building blocks; a saturated load NMOS inverter (on the
|
||||||
|
* right hand side of the schematics) with a buffer / bias input stage
|
||||||
|
* consisting of a variable saturated load NMOS inverter (on the left hand
|
||||||
|
* side of the schematics).
|
||||||
|
*
|
||||||
|
* Provided a reasonably high input impedance and a reasonably low output
|
||||||
|
* impedance, the "op-amp" can be modeled as a voltage transfer function
|
||||||
|
* mapping input voltage to output voltage.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Output buffer (NMOS voltage follower)
|
||||||
|
* -------------------------------------
|
||||||
|
* ~~~
|
||||||
|
*
|
||||||
|
* 12V
|
||||||
|
*
|
||||||
|
* |
|
||||||
|
* |
|
||||||
|
* ||--
|
||||||
|
* vi -----||
|
||||||
|
* ||--
|
||||||
|
* |
|
||||||
|
* |------ vo
|
||||||
|
* | (AUDIO
|
||||||
|
* Rext OUT)
|
||||||
|
* |
|
||||||
|
* |
|
||||||
|
*
|
||||||
|
* GND
|
||||||
|
*
|
||||||
|
* vi - input
|
||||||
|
* vo - output
|
||||||
|
* Rext - external resistor, 1kOhm
|
||||||
|
* ~~~
|
||||||
|
* Notes:
|
||||||
|
*
|
||||||
|
* The external resistor Rext is needed to complete the NMOS voltage follower,
|
||||||
|
* this resistor has a recommended value of 1kOhm.
|
||||||
|
*
|
||||||
|
* Die photographs show that actually, two NMOS transistors are used in the
|
||||||
|
* voltage follower. However the two transistors are coupled in parallel (all
|
||||||
|
* terminals are pairwise common), which implies that we can model the two
|
||||||
|
* transistors as one.
|
||||||
|
*/
|
||||||
|
class Filter6581 : public Filter
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/// Current volume amplifier setting.
|
||||||
|
unsigned short* currentGain;
|
||||||
|
|
||||||
|
/// Current filter/voice mixer setting.
|
||||||
|
unsigned short* currentMixer;
|
||||||
|
|
||||||
|
/// Filter input summer setting.
|
||||||
|
unsigned short* currentSummer;
|
||||||
|
|
||||||
|
/// Filter resonance value.
|
||||||
|
unsigned short* currentResonance;
|
||||||
|
|
||||||
|
const unsigned short* f0_dac;
|
||||||
|
|
||||||
|
unsigned short** mixer;
|
||||||
|
unsigned short** summer;
|
||||||
|
unsigned short** gain;
|
||||||
|
|
||||||
|
/// Filter highpass state.
|
||||||
|
int Vhp;
|
||||||
|
|
||||||
|
/// Filter bandpass state.
|
||||||
|
int Vbp;
|
||||||
|
|
||||||
|
/// Filter lowpass state.
|
||||||
|
int Vlp;
|
||||||
|
|
||||||
|
/// Filter external input.
|
||||||
|
int ve;
|
||||||
|
|
||||||
|
const int voiceScaleS14;
|
||||||
|
const int voiceDC;
|
||||||
|
|
||||||
|
/// VCR + associated capacitor connected to highpass output.
|
||||||
|
std::auto_ptr<Integrator> const hpIntegrator;
|
||||||
|
|
||||||
|
/// VCR + associated capacitor connected to lowpass output.
|
||||||
|
std::auto_ptr<Integrator> const bpIntegrator;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Filter6581() :
|
||||||
|
currentGain(0),
|
||||||
|
currentMixer(0),
|
||||||
|
currentSummer(0),
|
||||||
|
currentResonance(0),
|
||||||
|
f0_dac(FilterModelConfig::getInstance()->getDAC(0.5)),
|
||||||
|
mixer(FilterModelConfig::getInstance()->getMixer()),
|
||||||
|
summer(FilterModelConfig::getInstance()->getSummer()),
|
||||||
|
gain(FilterModelConfig::getInstance()->getGain()),
|
||||||
|
Vhp(0),
|
||||||
|
Vbp(0),
|
||||||
|
Vlp(0),
|
||||||
|
ve(0),
|
||||||
|
voiceScaleS14(FilterModelConfig::getInstance()->getVoiceScaleS14()),
|
||||||
|
voiceDC(FilterModelConfig::getInstance()->getVoiceDC()),
|
||||||
|
hpIntegrator(FilterModelConfig::getInstance()->buildIntegrator()),
|
||||||
|
bpIntegrator(FilterModelConfig::getInstance()->buildIntegrator())
|
||||||
|
{
|
||||||
|
input(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Filter6581();
|
||||||
|
|
||||||
|
int clock(int voice1, int voice2, int voice3);
|
||||||
|
|
||||||
|
void input(int sample) { ve = (sample * voiceScaleS14 * 3 >> 10) + mixer[0][0]; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set filter cutoff frequency.
|
||||||
|
*/
|
||||||
|
void updatedCenterFrequency();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set filter resonance.
|
||||||
|
*
|
||||||
|
* In the MOS 6581, 1/Q is controlled linearly by res.
|
||||||
|
*/
|
||||||
|
void updatedResonance() { currentResonance = gain[~res & 0xf]; }
|
||||||
|
|
||||||
|
void updatedMixing();
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Set filter curve type based on single parameter.
|
||||||
|
*
|
||||||
|
* @param curvePosition 0 .. 1, where 0 sets center frequency high ("light") and 1 sets it low ("dark"), default is 0.5
|
||||||
|
*/
|
||||||
|
void setFilterCurve(double curvePosition);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace reSIDfp
|
||||||
|
|
||||||
|
#if RESID_INLINING || defined(FILTER6581_CPP)
|
||||||
|
|
||||||
|
#include "Integrator.h"
|
||||||
|
|
||||||
|
namespace reSIDfp
|
||||||
|
{
|
||||||
|
|
||||||
|
RESID_INLINE
|
||||||
|
int Filter6581::clock(int voice1, int voice2, int voice3)
|
||||||
|
{
|
||||||
|
voice1 = (voice1 * voiceScaleS14 >> 18) + voiceDC;
|
||||||
|
voice2 = (voice2 * voiceScaleS14 >> 18) + voiceDC;
|
||||||
|
voice3 = (voice3 * voiceScaleS14 >> 18) + voiceDC;
|
||||||
|
|
||||||
|
int Vi = 0;
|
||||||
|
int Vo = 0;
|
||||||
|
|
||||||
|
(filt1 ? Vi : Vo) += voice1;
|
||||||
|
(filt2 ? Vi : Vo) += voice2;
|
||||||
|
|
||||||
|
// NB! Voice 3 is not silenced by voice3off if it is routed
|
||||||
|
// through the filter.
|
||||||
|
if (filt3) Vi += voice3;
|
||||||
|
else if (!voice3off) Vo += voice3;
|
||||||
|
|
||||||
|
(filtE ? Vi : Vo) += ve;
|
||||||
|
|
||||||
|
const int oldVhp = Vhp;
|
||||||
|
Vhp = currentSummer[currentResonance[Vbp] + Vlp + Vi];
|
||||||
|
Vlp = bpIntegrator->solve(Vbp);
|
||||||
|
Vbp = hpIntegrator->solve(oldVhp);
|
||||||
|
|
||||||
|
if (lp) Vo += Vlp;
|
||||||
|
if (bp) Vo += Vbp;
|
||||||
|
if (hp) Vo += Vhp;
|
||||||
|
|
||||||
|
return currentGain[currentMixer[Vo]] - (1 << 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace reSIDfp
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,438 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2011-2013 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
* Copyright 2007-2010 Antti Lankila
|
||||||
|
* Copyright 2000-2001 Simon White
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SIDPLAYER_H
|
||||||
|
#define SIDPLAYER_H
|
||||||
|
|
||||||
|
static const uint8_t sidplayer1[] =
|
||||||
|
{
|
||||||
|
0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x61, 0xe1, 0x60, 0x01, 0x02, 0x04, 0x00, 0x07, 0x0e, 0x02, 0x02, 0xfe, 0x02, 0x02, 0xfe,
|
||||||
|
0xfe, 0x00, 0x01, 0x00, 0xff, 0x00, 0x02, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x1e, 0x18, 0x8b, 0x7e,
|
||||||
|
0xfa, 0x06, 0xac, 0xf3, 0xe6, 0x8f, 0xf8, 0x2e, 0x86, 0x8e, 0x96, 0x9f, 0xa8, 0xb3, 0xbd, 0xc8,
|
||||||
|
0xd4, 0xe1, 0xee, 0xfd, 0x8c, 0x78, 0x64, 0x50, 0x3c, 0x28, 0x14, 0x00, 0x00, 0x02, 0x03, 0x05,
|
||||||
|
0x07, 0x08, 0x0a, 0x0c, 0x0d, 0x0f, 0x11, 0x12, 0x00, 0xe0, 0x00, 0x05, 0x0a, 0x0f, 0xf9, 0x00,
|
||||||
|
0xf5, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40, 0x00, 0x00,
|
||||||
|
0x50, 0x00, 0x00, 0x60, 0x00, 0x00, 0x70, 0x00, 0x00, 0x80, 0x00, 0x00, 0x90, 0x00, 0x00, 0xa0,
|
||||||
|
0x00, 0xa9, 0x00, 0x8d, 0x00, 0xe0, 0xa2, 0x95, 0xa0, 0x42, 0xad, 0xa6, 0x02, 0xf0, 0x04, 0xa2,
|
||||||
|
0x25, 0xa0, 0x40, 0x8e, 0x5b, 0xe1, 0x8c, 0x5c, 0xe1, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea,
|
||||||
|
0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea,
|
||||||
|
0xea, 0x60, 0xa9, 0x00, 0x8d, 0x00, 0xe0, 0x86, 0x61, 0x84, 0x62, 0xa0, 0xbc, 0x99, 0x00, 0xe0,
|
||||||
|
0x88, 0xd0, 0xfa, 0xa0, 0x72, 0x99, 0xbc, 0xe0, 0x88, 0xd0, 0xfa, 0x8d, 0x15, 0xd4, 0x8d, 0x16,
|
||||||
|
0xd4, 0xa9, 0x08, 0x8d, 0x25, 0xe0, 0x8d, 0x17, 0xd4, 0x8d, 0x26, 0xe0, 0x8d, 0x18, 0xd4, 0xa9,
|
||||||
|
0x90, 0x8d, 0x27, 0xe0, 0xa9, 0x60, 0x8d, 0x28, 0xe0, 0xa9, 0x0c, 0x8d, 0x29, 0xe0, 0xad, 0x5b,
|
||||||
|
0xe1, 0x8d, 0x2d, 0xe0, 0xad, 0x5c, 0xe1, 0x8d, 0x2e, 0xe0, 0xa9, 0xff, 0x8d, 0xcc, 0xe0, 0xa9,
|
||||||
|
0xd4, 0x85, 0x64, 0xa2, 0x02, 0xa9, 0xff, 0x9d, 0x0b, 0xe0, 0xa9, 0x01, 0x9d, 0x30, 0xe0, 0x9d,
|
||||||
|
0x2a, 0xe0, 0x8a, 0x9d, 0x33, 0xe0, 0x9d, 0xae, 0xe0, 0xa9, 0x04, 0x9d, 0x39, 0xe0, 0xbd, 0xa8,
|
||||||
|
0xe1, 0x9d, 0xba, 0xe0, 0xa9, 0x5b, 0x9d, 0x7e, 0xe0, 0xbd, 0x65, 0xe1, 0x85, 0x63, 0xa9, 0x00,
|
||||||
|
0xa8, 0x91, 0x63, 0xc8, 0x91, 0x63, 0xc8, 0x91, 0x63, 0xa9, 0x08, 0x9d, 0x17, 0xe0, 0x9d, 0x9c,
|
||||||
|
0xe0, 0xc8, 0x91, 0x63, 0xc8, 0x91, 0x63, 0xa9, 0x40, 0x9d, 0x1a, 0xe0, 0x91, 0x63, 0xa9, 0x20,
|
||||||
|
0x9d, 0x1d, 0xe0, 0xc8, 0x91, 0x63, 0xa9, 0xf5, 0x9d, 0x20, 0xe0, 0xc8, 0x91, 0x63, 0xca, 0x10,
|
||||||
|
0xa4, 0x8a, 0xa2, 0x17, 0x9d, 0x3e, 0xe1, 0xca, 0x10, 0xfa, 0xa5, 0x61, 0x18, 0x69, 0x06, 0x85,
|
||||||
|
0x63, 0xa9, 0x00, 0xaa, 0xa8, 0x65, 0x62, 0x85, 0x64, 0x9d, 0xab, 0xe0, 0x9d, 0xb4, 0xe0, 0xa5,
|
||||||
|
0x63, 0x9d, 0xa8, 0xe0, 0x9d, 0xb1, 0xe0, 0x18, 0x71, 0x61, 0x85, 0x63, 0xa5, 0x64, 0xc8, 0x71,
|
||||||
|
0x61, 0xc8, 0xe8, 0xe0, 0x03, 0xd0, 0xe0, 0xa6, 0x63, 0xa8, 0x60, 0xa9, 0x00, 0x8d, 0x04, 0xd4,
|
||||||
|
0x8d, 0x0b, 0xd4, 0x8d, 0x12, 0xd4, 0x8d, 0x01, 0xd4, 0x8d, 0x08, 0xd4, 0x8d, 0x0f, 0xd4, 0xa9,
|
||||||
|
0x08, 0x8d, 0x17, 0xd4, 0xad, 0x5b, 0xe1, 0x8d, 0x04, 0xdc, 0xad, 0x5c, 0xe1, 0x8d, 0x05, 0xdc,
|
||||||
|
0x60, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0x60,
|
||||||
|
0xa9, 0x08, 0x8d, 0x00, 0xe0, 0x6c, 0x5d, 0xe1, 0xea, 0xea, 0xea, 0xad, 0x00, 0xe0, 0x30, 0xf0,
|
||||||
|
0x09, 0x80, 0xa8, 0x29, 0x07, 0xf0, 0xee, 0xd8, 0x8c, 0x00, 0xe0, 0xea, 0xa5, 0xfb, 0x8d, 0x56,
|
||||||
|
0xe1, 0xa5, 0xfc, 0x8d, 0x57, 0xe1, 0xa5, 0xfd, 0x8d, 0x58, 0xe1, 0xa5, 0xfe, 0x8d, 0x59, 0xe1,
|
||||||
|
0xa5, 0xff, 0x8d, 0x5a, 0xe1, 0xad, 0x23, 0xe0, 0x18, 0x6d, 0xd9, 0xe0, 0x48, 0x29, 0x07, 0xa8,
|
||||||
|
0xad, 0xdc, 0xe0, 0x69, 0x00, 0x85, 0xff, 0x68, 0x46, 0xff, 0x6a, 0x46, 0xff, 0x6a, 0x46, 0xff,
|
||||||
|
0x6a, 0x18, 0x6d, 0x24, 0xe0, 0x8c, 0x15, 0xd4, 0x8d, 0x16, 0xd4, 0xad, 0x25, 0xe0, 0x8d, 0x17,
|
||||||
|
0xd4, 0xad, 0x26, 0xe0, 0x8d, 0x18, 0xd4, 0xa9, 0xd4, 0x85, 0xfc, 0xa2, 0x00, 0xad, 0x00, 0xe0,
|
||||||
|
0x3d, 0x62, 0xe1, 0xf0, 0x51, 0xbd, 0x65, 0xe1, 0x85, 0xfb, 0xbd, 0x0e, 0xe0, 0x18, 0x7d, 0x51,
|
||||||
|
0xe0, 0xa8, 0xbd, 0x11, 0xe0, 0x7d, 0x54, 0xe0, 0x48, 0x98, 0x18, 0x7d, 0xcd, 0xe0, 0xa0, 0x00,
|
||||||
|
0x91, 0xfb, 0x68, 0x7d, 0xd0, 0xe0, 0xc8, 0x91, 0xfb, 0xbd, 0x14, 0xe0, 0x18, 0x7d, 0x69, 0xe0,
|
||||||
|
0x85, 0xff, 0xbd, 0x17, 0xe0, 0x7d, 0x6c, 0xe0, 0x48, 0xa5, 0xff, 0x18, 0x7d, 0xd3, 0xe0, 0xc8,
|
||||||
|
0x91, 0xfb, 0x68, 0x7d, 0xd6, 0xe0, 0xc8, 0x91, 0xfb, 0xbd, 0x1d, 0xe0, 0xc8, 0xc8, 0x91, 0xfb,
|
||||||
|
0xbd, 0x20, 0xe0, 0xc8, 0x91, 0xfb, 0xe8, 0xe0, 0x03, 0xd0, 0xa2, 0xac, 0x1a, 0xe0, 0xae, 0x1b,
|
||||||
|
0xe0, 0xad, 0x1c, 0xe0, 0x8c, 0x04, 0xd4, 0x8e, 0x0b, 0xd4, 0x8d, 0x12, 0xd4, 0xae, 0x2d, 0xe0,
|
||||||
|
0xac, 0x2e, 0xe0, 0x8e, 0x04, 0xdc, 0x8c, 0x05, 0xdc, 0xad, 0x1b, 0xd4, 0x8d, 0xbe, 0xe0, 0xad,
|
||||||
|
0x1c, 0xd4, 0x8d, 0xbf, 0xe0, 0xa2, 0x00, 0xad, 0x00, 0xe0, 0x3d, 0x62, 0xe1, 0xf0, 0x10, 0x8e,
|
||||||
|
0x2f, 0xe0, 0x20, 0x36, 0xe5, 0xad, 0x00, 0xe0, 0x29, 0x78, 0xf0, 0x03, 0x4c, 0x0c, 0xe5, 0xe8,
|
||||||
|
0xe0, 0x03, 0xd0, 0xe3, 0xad, 0xc9, 0xe0, 0xd0, 0x52, 0xad, 0xca, 0xe0, 0x0d, 0xcb, 0xe0, 0xf0,
|
||||||
|
0x78, 0xad, 0xdf, 0xe0, 0xd0, 0x28, 0xad, 0xca, 0xe0, 0xf0, 0x28, 0x18, 0x6d, 0xbd, 0xe0, 0xb0,
|
||||||
|
0x07, 0xcd, 0xcc, 0xe0, 0x90, 0x60, 0xf0, 0x5e, 0xa9, 0x00, 0x8d, 0xdf, 0xe0, 0xad, 0xcb, 0xe0,
|
||||||
|
0xf0, 0x54, 0xee, 0xdf, 0xe0, 0xad, 0xbd, 0xe0, 0xed, 0xcb, 0xe0, 0x4c, 0xb4, 0xe4, 0xad, 0xcb,
|
||||||
|
0xe0, 0xf0, 0xd3, 0xad, 0xbd, 0xe0, 0x38, 0xed, 0xcb, 0xe0, 0xb0, 0x3a, 0xa9, 0x00, 0x8d, 0xdf,
|
||||||
|
0xe0, 0xad, 0xca, 0xe0, 0xd0, 0x30, 0xee, 0xdf, 0xe0, 0xd0, 0x28, 0xce, 0xe0, 0xe0, 0xd0, 0x29,
|
||||||
|
0xad, 0xdf, 0xe0, 0xd0, 0x11, 0xee, 0xdf, 0xe0, 0xad, 0xcb, 0xe0, 0xd0, 0x02, 0xa9, 0x20, 0x8d,
|
||||||
|
0xe0, 0xe0, 0xa9, 0x00, 0xf0, 0x10, 0xce, 0xdf, 0xe0, 0xad, 0xca, 0xe0, 0xd0, 0x02, 0xa9, 0x20,
|
||||||
|
0x8d, 0xe0, 0xe0, 0xad, 0xcc, 0xe0, 0x8d, 0xbd, 0xe0, 0xa2, 0x00, 0xbd, 0xc3, 0xe0, 0xf0, 0x44,
|
||||||
|
0xa9, 0x00, 0x85, 0xff, 0xbc, 0xc0, 0xe0, 0xb9, 0xbd, 0xe0, 0xbc, 0xc6, 0xe0, 0xf0, 0x0e, 0x30,
|
||||||
|
0x08, 0x0a, 0x26, 0xff, 0x88, 0xd0, 0xfa, 0xf0, 0x04, 0x4a, 0xc8, 0xd0, 0xfc, 0xbc, 0xc3, 0xe0,
|
||||||
|
0x88, 0xd0, 0x0b, 0x9d, 0xcd, 0xe0, 0xa5, 0xff, 0x9d, 0xd0, 0xe0, 0x4c, 0x02, 0xe5, 0x88, 0xd0,
|
||||||
|
0x0b, 0x9d, 0xd3, 0xe0, 0xa5, 0xff, 0x9d, 0xd6, 0xe0, 0x4c, 0x02, 0xe5, 0x8d, 0xd9, 0xe0, 0xa5,
|
||||||
|
0xff, 0x8d, 0xdc, 0xe0, 0xe8, 0xe0, 0x03, 0xd0, 0xb2, 0xad, 0x00, 0xe0, 0x29, 0x7f, 0x8d, 0x00,
|
||||||
|
0xe0, 0xad, 0x56, 0xe1, 0x85, 0xfb, 0xad, 0x57, 0xe1, 0x85, 0xfc, 0xad, 0x58, 0xe1, 0x85, 0xfd,
|
||||||
|
0xad, 0x59, 0xe1, 0x85, 0xfe, 0xad, 0x5a, 0xe1, 0x85, 0xff, 0x6c, 0x5d, 0xe1, 0xbd, 0x60, 0xe0,
|
||||||
|
0xd0, 0x03, 0x4c, 0x9f, 0xe6, 0x4c, 0xba, 0xe5, 0xde, 0x30, 0xe0, 0xd0, 0x03, 0x4c, 0xa0, 0xe6,
|
||||||
|
0xbd, 0x36, 0xe0, 0x30, 0xe8, 0xd0, 0x1a, 0xbd, 0x3f, 0xe0, 0xf0, 0x05, 0xde, 0x3f, 0xe0, 0xd0,
|
||||||
|
0x10, 0xbd, 0x39, 0xe0, 0xdd, 0x30, 0xe0, 0x90, 0x08, 0xbd, 0x1a, 0xe0, 0x29, 0xfe, 0x9d, 0x1a,
|
||||||
|
0xe0, 0xbd, 0x42, 0xe0, 0xf0, 0x56, 0x0a, 0xbd, 0x0e, 0xe0, 0xb0, 0x1d, 0x7d, 0x45, 0xe0, 0x9d,
|
||||||
|
0x0e, 0xe0, 0xa8, 0xbd, 0x11, 0xe0, 0x7d, 0x48, 0xe0, 0x9d, 0x11, 0xe0, 0x48, 0x98, 0xdd, 0x8d,
|
||||||
|
0xe0, 0x68, 0xfd, 0x90, 0xe0, 0xb0, 0x1f, 0x90, 0x2e, 0xfd, 0x45, 0xe0, 0x9d, 0x0e, 0xe0, 0xbd,
|
||||||
|
0x11, 0xe0, 0xfd, 0x48, 0xe0, 0x9d, 0x11, 0xe0, 0xbd, 0x8d, 0xe0, 0xdd, 0x0e, 0xe0, 0xbd, 0x90,
|
||||||
|
0xe0, 0xfd, 0x11, 0xe0, 0x90, 0x11, 0xbd, 0x8d, 0xe0, 0x9d, 0x0e, 0xe0, 0xbd, 0x90, 0xe0, 0x9d,
|
||||||
|
0x11, 0xe0, 0xa9, 0x00, 0x9d, 0x42, 0xe0, 0xbd, 0x60, 0xe0, 0xf0, 0x55, 0xbd, 0x4b, 0xe0, 0xf0,
|
||||||
|
0x4b, 0xa0, 0x00, 0xde, 0x4e, 0xe0, 0xd0, 0x31, 0xbd, 0x51, 0xe0, 0x1d, 0x54, 0xe0, 0xd0, 0x1b,
|
||||||
|
0xbd, 0x5d, 0xe0, 0x9d, 0x57, 0xe0, 0x9d, 0x4e, 0xe0, 0xbd, 0x4b, 0xe0, 0x0a, 0xbd, 0x5a, 0xe0,
|
||||||
|
0x90, 0x04, 0x49, 0xff, 0x69, 0x00, 0x9d, 0x4b, 0xe0, 0xd0, 0x10, 0xbd, 0x57, 0xe0, 0x9d, 0x4e,
|
||||||
|
0xe0, 0x98, 0x38, 0xfd, 0x4b, 0xe0, 0x9d, 0x4b, 0xe0, 0xc9, 0x00, 0x10, 0x01, 0x88, 0x18, 0x7d,
|
||||||
|
0x51, 0xe0, 0x9d, 0x51, 0xe0, 0x98, 0x7d, 0x54, 0xe0, 0x9d, 0x54, 0xe0, 0xbd, 0x36, 0xe0, 0x30,
|
||||||
|
0x15, 0xbd, 0x93, 0xe0, 0xf0, 0x10, 0x18, 0x7d, 0x14, 0xe0, 0x9d, 0x14, 0xe0, 0xbd, 0x96, 0xe0,
|
||||||
|
0x7d, 0x17, 0xe0, 0x9d, 0x17, 0xe0, 0xbd, 0x63, 0xe0, 0xf0, 0x4b, 0xa0, 0x00, 0xde, 0x66, 0xe0,
|
||||||
|
0xd0, 0x31, 0xbd, 0x69, 0xe0, 0x1d, 0x6c, 0xe0, 0xd0, 0x1b, 0xbd, 0x72, 0xe0, 0x9d, 0x6f, 0xe0,
|
||||||
|
0x9d, 0x66, 0xe0, 0xbd, 0x63, 0xe0, 0x0a, 0xbd, 0x75, 0xe0, 0x90, 0x04, 0x49, 0xff, 0x69, 0x00,
|
||||||
|
0x9d, 0x63, 0xe0, 0xd0, 0x10, 0xbd, 0x6f, 0xe0, 0x9d, 0x66, 0xe0, 0x98, 0x38, 0xfd, 0x63, 0xe0,
|
||||||
|
0x9d, 0x63, 0xe0, 0xc9, 0x00, 0x10, 0x01, 0x88, 0x18, 0x7d, 0x69, 0xe0, 0x9d, 0x69, 0xe0, 0x98,
|
||||||
|
0x7d, 0x6c, 0xe0, 0x9d, 0x6c, 0xe0, 0xbd, 0x36, 0xe0, 0x10, 0x03, 0x4c, 0x9f, 0xe6, 0xa0, 0x00,
|
||||||
|
0xbd, 0xa2, 0xe0, 0xf0, 0x1c, 0x10, 0x01, 0xc8, 0x18, 0x6d, 0x23, 0xe0, 0x48, 0x29, 0x07, 0x8d,
|
||||||
|
0x23, 0xe0, 0x68, 0x6a, 0x4a, 0x4a, 0x18, 0x79, 0xa6, 0xe1, 0x18, 0x6d, 0x24, 0xe0, 0x8d, 0x24,
|
||||||
|
0xe0, 0x60, 0xbd, 0xa8, 0xe0, 0x85, 0xfd, 0xbd, 0xab, 0xe0, 0x85, 0xfe, 0xd0, 0x04, 0x60, 0x20,
|
||||||
|
0x98, 0xe8, 0xad, 0x00, 0xe0, 0x3d, 0x62, 0xe1, 0xf0, 0xf4, 0xa0, 0x00, 0xb1, 0xfd, 0x85, 0xff,
|
||||||
|
0xc8, 0xb1, 0xfd, 0xa8, 0xa5, 0xfd, 0x18, 0x69, 0x02, 0x85, 0xfd, 0x9d, 0xa8, 0xe0, 0xa5, 0xfe,
|
||||||
|
0x69, 0x00, 0x85, 0xfe, 0x9d, 0xab, 0xe0, 0xa5, 0xff, 0x29, 0x03, 0xd0, 0xd2, 0xbd, 0x8d, 0xe0,
|
||||||
|
0x9d, 0x0e, 0xe0, 0xbd, 0x90, 0xe0, 0x9d, 0x11, 0xe0, 0xa5, 0xff, 0x9d, 0x05, 0xe0, 0x98, 0x9d,
|
||||||
|
0x02, 0xe0, 0x29, 0x07, 0xa8, 0xb9, 0x67, 0xe1, 0x8d, 0x6f, 0xe1, 0xbd, 0x02, 0xe0, 0x29, 0x38,
|
||||||
|
0x4a, 0x4a, 0x4a, 0x7d, 0x81, 0xe0, 0x85, 0xfd, 0xbd, 0x02, 0xe0, 0x29, 0xc0, 0x0a, 0x2a, 0x2a,
|
||||||
|
0xa8, 0xb9, 0x6f, 0xe1, 0x85, 0xfe, 0xbd, 0x02, 0xe0, 0x29, 0x07, 0xf0, 0x62, 0xa8, 0xb9, 0x72,
|
||||||
|
0xe1, 0x65, 0xfe, 0x18, 0x7d, 0x84, 0xe0, 0x10, 0x05, 0x18, 0x69, 0x0c, 0xe6, 0xfd, 0xc9, 0x0c,
|
||||||
|
0x90, 0x04, 0xe9, 0x0c, 0xc6, 0xfd, 0x85, 0xfe, 0xa8, 0xb9, 0x86, 0xe1, 0x85, 0xff, 0xb9, 0x7a,
|
||||||
|
0xe1, 0xa4, 0xfd, 0x88, 0x30, 0x06, 0x46, 0xff, 0x6a, 0x88, 0x10, 0xfa, 0x18, 0x7d, 0x87, 0xe0,
|
||||||
|
0x9d, 0x8d, 0xe0, 0xa5, 0xff, 0x7d, 0x8a, 0xe0, 0x9d, 0x90, 0xe0, 0xbd, 0x05, 0xe0, 0xd0, 0x03,
|
||||||
|
0x4c, 0xa0, 0xe6, 0xbd, 0x45, 0xe0, 0x1d, 0x48, 0xe0, 0xf0, 0x16, 0xbd, 0x0e, 0xe0, 0xdd, 0x8d,
|
||||||
|
0xe0, 0xbd, 0x11, 0xe0, 0xfd, 0x90, 0xe0, 0xa9, 0xfe, 0x6a, 0x9d, 0x42, 0xe0, 0x90, 0x11, 0xf0,
|
||||||
|
0x4a, 0x9d, 0x42, 0xe0, 0xbd, 0x8d, 0xe0, 0x9d, 0x0e, 0xe0, 0xbd, 0x90, 0xe0, 0x9d, 0x11, 0xe0,
|
||||||
|
0xbd, 0x36, 0xe0, 0x0a, 0xd0, 0x35, 0xbd, 0x93, 0xe0, 0xf0, 0x0c, 0xbd, 0x99, 0xe0, 0x9d, 0x14,
|
||||||
|
0xe0, 0xbd, 0x9c, 0xe0, 0x9d, 0x17, 0xe0, 0xbd, 0x9f, 0xe0, 0xf0, 0x0f, 0xa4, 0xfd, 0x18, 0x79,
|
||||||
|
0x92, 0xe1, 0xa4, 0xfe, 0x18, 0x79, 0x9a, 0xe1, 0x18, 0x90, 0x08, 0xbd, 0xa2, 0xe0, 0xf0, 0x0b,
|
||||||
|
0xbd, 0xa5, 0xe0, 0x8d, 0x24, 0xe0, 0xa9, 0x00, 0x8d, 0x23, 0xe0, 0xbd, 0x3c, 0xe0, 0x9d, 0x3f,
|
||||||
|
0xe0, 0xbd, 0x05, 0xe0, 0x29, 0x40, 0x9d, 0x36, 0xe0, 0xbd, 0x05, 0xe0, 0x4a, 0x4a, 0x29, 0x07,
|
||||||
|
0xd0, 0x30, 0xbd, 0x05, 0xe0, 0x30, 0x14, 0xad, 0x27, 0xe0, 0x29, 0x3c, 0xd0, 0x1e, 0xad, 0x27,
|
||||||
|
0xe0, 0x0a, 0x2a, 0x2a, 0xd0, 0x02, 0xa9, 0x04, 0x4c, 0x70, 0xe8, 0xad, 0x28, 0xe0, 0xf0, 0x0c,
|
||||||
|
0x29, 0x3f, 0xd0, 0x08, 0xad, 0x28, 0xe0, 0x0a, 0x2a, 0x2a, 0xd0, 0x66, 0xa9, 0x10, 0x8d, 0x00,
|
||||||
|
0xe0, 0x60, 0xc9, 0x01, 0xd0, 0x13, 0xbd, 0x05, 0xe0, 0x29, 0x20, 0xd0, 0x06, 0xad, 0x29, 0xe0,
|
||||||
|
0x4c, 0x70, 0xe8, 0xbd, 0x2a, 0xe0, 0x4c, 0x70, 0xe8, 0xa8, 0xbd, 0x05, 0xe0, 0x29, 0xa0, 0xc9,
|
||||||
|
0x80, 0xf0, 0x30, 0x85, 0xff, 0x18, 0xad, 0x27, 0xe0, 0xd0, 0x01, 0x38, 0x88, 0x88, 0xf0, 0x06,
|
||||||
|
0x6a, 0xb0, 0x4e, 0x88, 0xd0, 0xfa, 0xa4, 0xff, 0x85, 0xff, 0xf0, 0x26, 0x46, 0xff, 0xb0, 0x41,
|
||||||
|
0xf0, 0x42, 0x65, 0xff, 0xb0, 0x3e, 0xc8, 0x10, 0x19, 0x46, 0xff, 0xb0, 0x34, 0x65, 0xff, 0x90,
|
||||||
|
0x11, 0xb0, 0x31, 0xad, 0x28, 0xe0, 0xf0, 0x29, 0x88, 0x88, 0xf0, 0x06, 0x4a, 0xb0, 0x22, 0x88,
|
||||||
|
0xd0, 0xfa, 0x9d, 0x30, 0xe0, 0xbd, 0x1a, 0xe0, 0x29, 0xf6, 0x9d, 0x1a, 0xe0, 0x38, 0xbd, 0x02,
|
||||||
|
0xe0, 0x29, 0x07, 0xd0, 0x03, 0x7e, 0x36, 0xe0, 0xbd, 0x1a, 0xe0, 0x69, 0x00, 0x9d, 0x1a, 0xe0,
|
||||||
|
0x60, 0xa9, 0x10, 0x2c, 0xa9, 0x18, 0x8d, 0x00, 0xe0, 0x60, 0x98, 0x48, 0xa5, 0xff, 0x4a, 0x90,
|
||||||
|
0x03, 0x4c, 0x42, 0xea, 0x4a, 0x4a, 0xb0, 0x1e, 0x4a, 0xb0, 0x0e, 0x9d, 0x9c, 0xe0, 0x9d, 0x17,
|
||||||
|
0xe0, 0x68, 0x9d, 0x99, 0xe0, 0x9d, 0x14, 0xe0, 0x60, 0x4a, 0x90, 0x02, 0x09, 0xf8, 0x9d, 0x8a,
|
||||||
|
0xe0, 0x68, 0x9d, 0x87, 0xe0, 0x60, 0x4a, 0xb0, 0x03, 0x4c, 0x4a, 0xe9, 0x4a, 0xb0, 0x61, 0x4a,
|
||||||
|
0xb0, 0x0f, 0xd0, 0x08, 0x68, 0x9d, 0xa5, 0xe0, 0x8d, 0x24, 0xe0, 0x60, 0x68, 0x9d, 0x3c, 0xe0,
|
||||||
|
0x60, 0xd0, 0x48, 0x68, 0x9d, 0x7e, 0xe0, 0xc9, 0x5b, 0xf0, 0x33, 0xa8, 0x4a, 0x4a, 0x4a, 0x38,
|
||||||
|
0xe9, 0x0b, 0x18, 0x7d, 0x84, 0xe0, 0x30, 0x0c, 0xc9, 0x0c, 0x90, 0x11, 0xe9, 0x0c, 0xde, 0x81,
|
||||||
|
0xe0, 0x4c, 0x0b, 0xe9, 0xc9, 0xf5, 0xb0, 0x05, 0x69, 0x0c, 0xfe, 0x81, 0xe0, 0x9d, 0x84, 0xe0,
|
||||||
|
0x98, 0x29, 0x07, 0x38, 0xe9, 0x03, 0x18, 0x7d, 0x81, 0xe0, 0x9d, 0x81, 0xe0, 0x60, 0xbd, 0x78,
|
||||||
|
0xe0, 0x9d, 0x81, 0xe0, 0xbd, 0x7b, 0xe0, 0x9d, 0x84, 0xe0, 0x60, 0x68, 0x9d, 0xc6, 0xe0, 0x60,
|
||||||
|
0x4a, 0xb0, 0x08, 0x9d, 0x0b, 0xe0, 0x68, 0x9d, 0x08, 0xe0, 0x60, 0x4a, 0x6a, 0x6a, 0x6d, 0x5b,
|
||||||
|
0xe1, 0x8d, 0x2d, 0xe0, 0x68, 0x6d, 0x5c, 0xe1, 0x8d, 0x2e, 0xe0, 0x60, 0x4a, 0x90, 0x03, 0x4c,
|
||||||
|
0xd3, 0xe9, 0x4a, 0xb0, 0x40, 0x4a, 0xb0, 0x17, 0x4a, 0xb0, 0x0f, 0x68, 0x8d, 0x27, 0xe0, 0x4a,
|
||||||
|
0x4a, 0x4a, 0xa8, 0xb9, 0xaf, 0xe1, 0x8d, 0x28, 0xe0, 0x60, 0x68, 0x9d, 0x5d, 0xe0, 0x60, 0x4a,
|
||||||
|
0xb0, 0x05, 0x68, 0x8d, 0x01, 0xe0, 0x60, 0x68, 0xf0, 0x11, 0x9d, 0x75, 0xe0, 0xbc, 0x63, 0xe0,
|
||||||
|
0xd0, 0x08, 0x9d, 0x63, 0xe0, 0xa9, 0x01, 0x9d, 0x66, 0xe0, 0x60, 0x9d, 0x63, 0xe0, 0x9d, 0x69,
|
||||||
|
0xe0, 0x9d, 0x6c, 0xe0, 0x60, 0x4a, 0xb0, 0x30, 0x4a, 0xb0, 0x05, 0x68, 0x9d, 0x39, 0xe0, 0x60,
|
||||||
|
0x68, 0xa0, 0x00, 0x4a, 0x90, 0x02, 0xc8, 0x18, 0x48, 0x29, 0x07, 0x79, 0xac, 0xe1, 0x9d, 0x78,
|
||||||
|
0xe0, 0x9d, 0x81, 0xe0, 0x68, 0x4a, 0x4a, 0x4a, 0x18, 0x79, 0xad, 0xe1, 0x9d, 0x7b, 0xe0, 0x9d,
|
||||||
|
0x84, 0xe0, 0xa9, 0x5b, 0x9d, 0x7e, 0xe0, 0x60, 0x4a, 0xb0, 0x05, 0x68, 0x9d, 0xa2, 0xe0, 0x60,
|
||||||
|
0x68, 0x8d, 0xcc, 0xe0, 0x60, 0x4a, 0xb0, 0x27, 0x4a, 0xb0, 0x0d, 0x4a, 0xb0, 0x05, 0x68, 0x8d,
|
||||||
|
0x29, 0xe0, 0x60, 0x68, 0x9d, 0x9f, 0xe0, 0x60, 0x4a, 0xb0, 0x0f, 0x68, 0x9d, 0x93, 0xe0, 0xa0,
|
||||||
|
0x00, 0x0a, 0x90, 0x01, 0x88, 0x98, 0x9d, 0x96, 0xe0, 0x60, 0x68, 0x9d, 0x72, 0xe0, 0x60, 0x4a,
|
||||||
|
0xb0, 0x1c, 0x4a, 0xb0, 0x15, 0x68, 0x9d, 0xb7, 0xe0, 0xa5, 0xfd, 0x9d, 0xb1, 0xe0, 0xa5, 0xfe,
|
||||||
|
0x9d, 0xb4, 0xe0, 0xbd, 0x33, 0xe0, 0x9d, 0xae, 0xe0, 0x60, 0x68, 0x6c, 0x5f, 0xe1, 0x4a, 0xb0,
|
||||||
|
0x1e, 0x68, 0xd0, 0x0a, 0x9d, 0x4b, 0xe0, 0x9d, 0x51, 0xe0, 0x9d, 0x54, 0xe0, 0x60, 0x9d, 0x5a,
|
||||||
|
0xe0, 0xbc, 0x4b, 0xe0, 0xd0, 0x08, 0x9d, 0x4b, 0xe0, 0xa9, 0x01, 0x9d, 0x4e, 0xe0, 0x60, 0x68,
|
||||||
|
0x9d, 0x2a, 0xe0, 0x60, 0x4a, 0x90, 0x08, 0x9d, 0x48, 0xe0, 0x68, 0x9d, 0x45, 0xe0, 0x60, 0x68,
|
||||||
|
0x4a, 0xb0, 0x61, 0x4a, 0xb0, 0x25, 0x4a, 0xb0, 0x05, 0x4a, 0xa0, 0xf0, 0xd0, 0x06, 0x0a, 0x0a,
|
||||||
|
0x0a, 0x0a, 0xa0, 0x0f, 0x85, 0xff, 0x98, 0xb0, 0x09, 0x3d, 0x1d, 0xe0, 0x05, 0xff, 0x9d, 0x1d,
|
||||||
|
0xe0, 0x60, 0x3d, 0x20, 0xe0, 0x05, 0xff, 0x9d, 0x20, 0xe0, 0x60, 0x4a, 0xb0, 0x38, 0x4a, 0xb0,
|
||||||
|
0x64, 0x85, 0xff, 0xbd, 0xba, 0xe0, 0xdd, 0xa9, 0xe1, 0xf0, 0x54, 0xfe, 0xba, 0xe0, 0xa8, 0xa5,
|
||||||
|
0xfd, 0x99, 0xe1, 0xe0, 0xa5, 0xfe, 0x99, 0xf0, 0xe0, 0xbd, 0x33, 0xe0, 0x99, 0x2f, 0xe1, 0xa4,
|
||||||
|
0xff, 0xb9, 0x17, 0xe1, 0xf0, 0x36, 0x85, 0xfe, 0xb9, 0xff, 0xe0, 0x85, 0xfd, 0xb9, 0x3e, 0xe1,
|
||||||
|
0x9d, 0x33, 0xe0, 0x60, 0xb0, 0x4b, 0x4a, 0xb0, 0x3c, 0xa8, 0xa5, 0xfd, 0x99, 0xff, 0xe0, 0xa5,
|
||||||
|
0xfe, 0x99, 0x17, 0xe1, 0xbd, 0x33, 0xe0, 0x99, 0x3e, 0xe1, 0xbd, 0xba, 0xe0, 0xdd, 0xa9, 0xe1,
|
||||||
|
0xf0, 0x0d, 0xfe, 0xba, 0xe0, 0xa8, 0xa9, 0x00, 0x99, 0xf0, 0xe0, 0x60, 0xa9, 0x30, 0x2c, 0xa9,
|
||||||
|
0x28, 0x8d, 0x00, 0xe0, 0x60, 0x0a, 0x0a, 0x0a, 0x0a, 0x4d, 0x25, 0xe0, 0x29, 0xf0, 0x4d, 0x25,
|
||||||
|
0xe0, 0x8d, 0x25, 0xe0, 0x60, 0x4d, 0x26, 0xe0, 0x29, 0x0f, 0x4d, 0x26, 0xe0, 0x8d, 0x26, 0xe0,
|
||||||
|
0x60, 0x4a, 0xb0, 0x0b, 0x4a, 0xb0, 0x04, 0x8d, 0xca, 0xe0, 0x60, 0x8d, 0xcb, 0xe0, 0x60, 0x4a,
|
||||||
|
0x90, 0x03, 0x4c, 0xa5, 0xeb, 0x4a, 0xa8, 0xf0, 0x21, 0x88, 0xf0, 0x34, 0x88, 0xf0, 0x42, 0x88,
|
||||||
|
0xf0, 0x4a, 0x88, 0xf0, 0x52, 0x88, 0xf0, 0x5c, 0x88, 0xf0, 0x66, 0x88, 0xf0, 0x73, 0x29, 0x07,
|
||||||
|
0x09, 0x10, 0xb0, 0x03, 0x4c, 0xb7, 0xea, 0x4c, 0x7f, 0xea, 0xac, 0x26, 0xe0, 0xb0, 0x07, 0xc8,
|
||||||
|
0x98, 0x29, 0x0f, 0xd0, 0x07, 0x60, 0x98, 0x29, 0x0f, 0xf0, 0x04, 0x88, 0x8c, 0x26, 0xe0, 0x60,
|
||||||
|
0xbd, 0x62, 0xe1, 0x49, 0xff, 0x2d, 0x25, 0xe0, 0x90, 0x03, 0x1d, 0x62, 0xe1, 0x8d, 0x25, 0xe0,
|
||||||
|
0x60, 0xbd, 0x1a, 0xe0, 0x29, 0xfb, 0x90, 0x55, 0x09, 0x04, 0xb0, 0x51, 0xbd, 0x1a, 0xe0, 0x29,
|
||||||
|
0xfd, 0x90, 0x4a, 0x09, 0x02, 0xb0, 0x46, 0xad, 0x25, 0xe0, 0x29, 0xf7, 0x90, 0x02, 0x09, 0x08,
|
||||||
|
0x8d, 0x25, 0xe0, 0x60, 0xad, 0x26, 0xe0, 0x29, 0x7f, 0x90, 0x02, 0x09, 0x80, 0x8d, 0x26, 0xe0,
|
||||||
|
0x60, 0x98, 0x8d, 0xbd, 0xe0, 0x8d, 0xdf, 0xe0, 0xc8, 0x8c, 0xe0, 0xe0, 0x2a, 0x8d, 0xc9, 0xe0,
|
||||||
|
0x60, 0x98, 0x2a, 0x9d, 0x60, 0xe0, 0x60, 0x4a, 0xb0, 0x27, 0x4a, 0xb0, 0x14, 0xd0, 0x02, 0xa9,
|
||||||
|
0x08, 0x0a, 0x0a, 0x0a, 0x0a, 0x5d, 0x1a, 0xe0, 0x29, 0xf0, 0x5d, 0x1a, 0xe0, 0x9d, 0x1a, 0xe0,
|
||||||
|
0x60, 0x0a, 0x0a, 0x0a, 0x0a, 0x4d, 0x26, 0xe0, 0x29, 0x70, 0x4d, 0x26, 0xe0, 0x8d, 0x26, 0xe0,
|
||||||
|
0x60, 0x4a, 0x90, 0x04, 0x9d, 0xc0, 0xe0, 0x60, 0xa8, 0xf0, 0x20, 0x88, 0xf0, 0x40, 0x88, 0xf0,
|
||||||
|
0x63, 0x29, 0x03, 0x9d, 0xc3, 0xe0, 0xa9, 0x00, 0x9d, 0xcd, 0xe0, 0x9d, 0xd0, 0xe0, 0x9d, 0xd3,
|
||||||
|
0xe0, 0x9d, 0xd6, 0xe0, 0x8d, 0xd9, 0xe0, 0x8d, 0xdc, 0xe0, 0x60, 0xbd, 0xb7, 0xe0, 0xf0, 0x05,
|
||||||
|
0xde, 0xb7, 0xe0, 0xf0, 0x12, 0xbd, 0x33, 0xe0, 0xdd, 0xae, 0xe0, 0xd0, 0x0b, 0xbd, 0xb1, 0xe0,
|
||||||
|
0x85, 0xfd, 0xbd, 0xb4, 0xe0, 0x85, 0xfe, 0x60, 0xa9, 0x38, 0x8d, 0x00, 0xe0, 0x60, 0xbd, 0xba,
|
||||||
|
0xe0, 0xdd, 0xa8, 0xe1, 0xf0, 0x18, 0xde, 0xba, 0xe0, 0xa8, 0x88, 0xb9, 0xf0, 0xe0, 0xf0, 0x0d,
|
||||||
|
0x85, 0xfe, 0xb9, 0xe1, 0xe0, 0x85, 0xfd, 0xb9, 0x2f, 0xe1, 0x9d, 0x33, 0xe0, 0x60, 0xa9, 0x20,
|
||||||
|
0x8d, 0x00, 0xe0, 0x60, 0xad, 0x00, 0xe0, 0x5d, 0x62, 0xe1, 0x8d, 0x00, 0xe0, 0xa9, 0x01, 0x9d,
|
||||||
|
0x30, 0xe0, 0x60, 0xad, 0x00, 0xe0, 0x29, 0x07, 0x8d, 0x81, 0xec, 0xd0, 0x03, 0x20, 0xe9, 0xe2,
|
||||||
|
0x60, 0x00, 0xa2, 0x51, 0xa0, 0xec, 0x8e, 0x5d, 0xe1, 0x8c, 0x5e, 0xe1, 0x20, 0xcf, 0xe1, 0xa2,
|
||||||
|
0x00, 0xa0, 0x09, 0x20, 0x00, 0xe2, 0xa9, 0x07, 0x8d, 0x00, 0xe0, 0x8d, 0x81, 0xec, 0x60, 0x00,
|
||||||
|
0x00, 0x00, 0xa9, 0x00, 0x29, 0xff, 0xf0, 0xf6, 0x4c, 0x29, 0xe3, 0xa9, 0x07, 0x8d, 0x00, 0xe0,
|
||||||
|
0x60
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t sidplayer2[] =
|
||||||
|
{
|
||||||
|
0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x61, 0xf1, 0x60, 0x01, 0x02, 0x04, 0x00, 0x07, 0x0e, 0x02, 0x02, 0xfe, 0x02, 0x02, 0xfe,
|
||||||
|
0xfe, 0x00, 0x01, 0x00, 0xff, 0x00, 0x02, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x1e, 0x18, 0x8b, 0x7e,
|
||||||
|
0xfa, 0x06, 0xac, 0xf3, 0xe6, 0x8f, 0xf8, 0x2e, 0x86, 0x8e, 0x96, 0x9f, 0xa8, 0xb3, 0xbd, 0xc8,
|
||||||
|
0xd4, 0xe1, 0xee, 0xfd, 0x8c, 0x78, 0x64, 0x50, 0x3c, 0x28, 0x14, 0x00, 0x00, 0x02, 0x03, 0x05,
|
||||||
|
0x07, 0x08, 0x0a, 0x0c, 0x0d, 0x0f, 0x11, 0x12, 0x00, 0xe0, 0x00, 0x05, 0x0a, 0x0f, 0xf9, 0x00,
|
||||||
|
0xf5, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40, 0x00, 0x00,
|
||||||
|
0x50, 0x00, 0x00, 0x60, 0x00, 0x00, 0x70, 0x00, 0x00, 0x80, 0x00, 0x00, 0x90, 0x00, 0x00, 0xa0,
|
||||||
|
0x00, 0xa9, 0x00, 0x8d, 0x00, 0xf0, 0xa2, 0x95, 0xa0, 0x42, 0xad, 0xa6, 0x02, 0xf0, 0x04, 0xa2,
|
||||||
|
0x25, 0xa0, 0x40, 0x8e, 0x5b, 0xf1, 0x8c, 0x5c, 0xf1, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea,
|
||||||
|
0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea,
|
||||||
|
0xea, 0x60, 0xa9, 0x00, 0x8d, 0x00, 0xf0, 0x86, 0x61, 0x84, 0x62, 0xa0, 0xbc, 0x99, 0x00, 0xf0,
|
||||||
|
0x88, 0xd0, 0xfa, 0xa0, 0x72, 0x99, 0xbc, 0xf0, 0x88, 0xd0, 0xfa, 0x8d, 0x15, 0xd5, 0x8d, 0x16,
|
||||||
|
0xd5, 0xa9, 0x08, 0x8d, 0x25, 0xf0, 0x8d, 0x17, 0xd5, 0x8d, 0x26, 0xf0, 0x8d, 0x18, 0xd5, 0xa9,
|
||||||
|
0x90, 0x8d, 0x27, 0xf0, 0xa9, 0x60, 0x8d, 0x28, 0xf0, 0xa9, 0x0c, 0x8d, 0x29, 0xf0, 0xad, 0x5b,
|
||||||
|
0xf1, 0x8d, 0x2d, 0xf0, 0xad, 0x5c, 0xf1, 0x8d, 0x2e, 0xf0, 0xa9, 0xff, 0x8d, 0xcc, 0xf0, 0xa9,
|
||||||
|
0xd5, 0x85, 0x64, 0xa2, 0x02, 0xa9, 0xff, 0x9d, 0x0b, 0xf0, 0xa9, 0x01, 0x9d, 0x30, 0xf0, 0x9d,
|
||||||
|
0x2a, 0xf0, 0x8a, 0x9d, 0x33, 0xf0, 0x9d, 0xae, 0xf0, 0xa9, 0x04, 0x9d, 0x39, 0xf0, 0xbd, 0xa8,
|
||||||
|
0xf1, 0x9d, 0xba, 0xf0, 0xa9, 0x5b, 0x9d, 0x7e, 0xf0, 0xbd, 0x65, 0xf1, 0x85, 0x63, 0xa9, 0x00,
|
||||||
|
0xa8, 0x91, 0x63, 0xc8, 0x91, 0x63, 0xc8, 0x91, 0x63, 0xa9, 0x08, 0x9d, 0x17, 0xf0, 0x9d, 0x9c,
|
||||||
|
0xf0, 0xc8, 0x91, 0x63, 0xc8, 0x91, 0x63, 0xa9, 0x40, 0x9d, 0x1a, 0xf0, 0x91, 0x63, 0xa9, 0x20,
|
||||||
|
0x9d, 0x1d, 0xf0, 0xc8, 0x91, 0x63, 0xa9, 0xf5, 0x9d, 0x20, 0xf0, 0xc8, 0x91, 0x63, 0xca, 0x10,
|
||||||
|
0xa4, 0x8a, 0xa2, 0x17, 0x9d, 0x3e, 0xf1, 0xca, 0x10, 0xfa, 0xa5, 0x61, 0x18, 0x69, 0x06, 0x85,
|
||||||
|
0x63, 0xa9, 0x00, 0xaa, 0xa8, 0x65, 0x62, 0x85, 0x64, 0x9d, 0xab, 0xf0, 0x9d, 0xb4, 0xf0, 0xa5,
|
||||||
|
0x63, 0x9d, 0xa8, 0xf0, 0x9d, 0xb1, 0xf0, 0x18, 0x71, 0x61, 0x85, 0x63, 0xa5, 0x64, 0xc8, 0x71,
|
||||||
|
0x61, 0xc8, 0xe8, 0xe0, 0x03, 0xd0, 0xe0, 0xa6, 0x63, 0xa8, 0x60, 0xa9, 0x00, 0x8d, 0x04, 0xd5,
|
||||||
|
0x8d, 0x0b, 0xd5, 0x8d, 0x12, 0xd5, 0x8d, 0x01, 0xd5, 0x8d, 0x08, 0xd5, 0x8d, 0x0f, 0xd5, 0xa9,
|
||||||
|
0x08, 0x8d, 0x17, 0xd5, 0xad, 0x5b, 0xf1, 0x8d, 0x04, 0xdc, 0xad, 0x5c, 0xf1, 0x8d, 0x05, 0xdc,
|
||||||
|
0x60, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0x60,
|
||||||
|
0xa9, 0x08, 0x8d, 0x00, 0xf0, 0x6c, 0x5d, 0xf1, 0xea, 0xea, 0xea, 0xad, 0x00, 0xf0, 0x30, 0xf0,
|
||||||
|
0x09, 0x80, 0xa8, 0x29, 0x07, 0xf0, 0xee, 0xd8, 0x8c, 0x00, 0xf0, 0xea, 0xa5, 0xfb, 0x8d, 0x56,
|
||||||
|
0xf1, 0xa5, 0xfc, 0x8d, 0x57, 0xf1, 0xa5, 0xfd, 0x8d, 0x58, 0xf1, 0xa5, 0xfe, 0x8d, 0x59, 0xf1,
|
||||||
|
0xa5, 0xff, 0x8d, 0x5a, 0xf1, 0xad, 0x23, 0xf0, 0x18, 0x6d, 0xd9, 0xf0, 0x48, 0x29, 0x07, 0xa8,
|
||||||
|
0xad, 0xdc, 0xf0, 0x69, 0x00, 0x85, 0xff, 0x68, 0x46, 0xff, 0x6a, 0x46, 0xff, 0x6a, 0x46, 0xff,
|
||||||
|
0x6a, 0x18, 0x6d, 0x24, 0xf0, 0x8c, 0x15, 0xd5, 0x8d, 0x16, 0xd5, 0xad, 0x25, 0xf0, 0x8d, 0x17,
|
||||||
|
0xd5, 0xad, 0x26, 0xf0, 0x8d, 0x18, 0xd5, 0xa9, 0xd5, 0x85, 0xfc, 0xa2, 0x00, 0xad, 0x00, 0xf0,
|
||||||
|
0x3d, 0x62, 0xf1, 0xf0, 0x51, 0xbd, 0x65, 0xf1, 0x85, 0xfb, 0xbd, 0x0e, 0xf0, 0x18, 0x7d, 0x51,
|
||||||
|
0xf0, 0xa8, 0xbd, 0x11, 0xf0, 0x7d, 0x54, 0xf0, 0x48, 0x98, 0x18, 0x7d, 0xcd, 0xf0, 0xa0, 0x00,
|
||||||
|
0x91, 0xfb, 0x68, 0x7d, 0xd0, 0xf0, 0xc8, 0x91, 0xfb, 0xbd, 0x14, 0xf0, 0x18, 0x7d, 0x69, 0xf0,
|
||||||
|
0x85, 0xff, 0xbd, 0x17, 0xf0, 0x7d, 0x6c, 0xf0, 0x48, 0xa5, 0xff, 0x18, 0x7d, 0xd3, 0xf0, 0xc8,
|
||||||
|
0x91, 0xfb, 0x68, 0x7d, 0xd6, 0xf0, 0xc8, 0x91, 0xfb, 0xbd, 0x1d, 0xf0, 0xc8, 0xc8, 0x91, 0xfb,
|
||||||
|
0xbd, 0x20, 0xf0, 0xc8, 0x91, 0xfb, 0xe8, 0xe0, 0x03, 0xd0, 0xa2, 0xac, 0x1a, 0xf0, 0xae, 0x1b,
|
||||||
|
0xf0, 0xad, 0x1c, 0xf0, 0x8c, 0x04, 0xd5, 0x8e, 0x0b, 0xd5, 0x8d, 0x12, 0xd5, 0xae, 0x2d, 0xf0,
|
||||||
|
0xac, 0x2e, 0xf0, 0x8e, 0x04, 0xdc, 0x8c, 0x05, 0xdc, 0xad, 0x1b, 0xd5, 0x8d, 0xbe, 0xf0, 0xad,
|
||||||
|
0x1c, 0xd5, 0x8d, 0xbf, 0xf0, 0xa2, 0x00, 0xad, 0x00, 0xf0, 0x3d, 0x62, 0xf1, 0xf0, 0x10, 0x8e,
|
||||||
|
0x2f, 0xf0, 0x20, 0x36, 0xf5, 0xad, 0x00, 0xf0, 0x29, 0x78, 0xf0, 0x03, 0x4c, 0x0c, 0xf5, 0xe8,
|
||||||
|
0xe0, 0x03, 0xd0, 0xe3, 0xad, 0xc9, 0xf0, 0xd0, 0x52, 0xad, 0xca, 0xf0, 0x0d, 0xcb, 0xf0, 0xf0,
|
||||||
|
0x78, 0xad, 0xdf, 0xf0, 0xd0, 0x28, 0xad, 0xca, 0xf0, 0xf0, 0x28, 0x18, 0x6d, 0xbd, 0xf0, 0xb0,
|
||||||
|
0x07, 0xcd, 0xcc, 0xf0, 0x90, 0x60, 0xf0, 0x5e, 0xa9, 0x00, 0x8d, 0xdf, 0xf0, 0xad, 0xcb, 0xf0,
|
||||||
|
0xf0, 0x54, 0xee, 0xdf, 0xf0, 0xad, 0xbd, 0xf0, 0xed, 0xcb, 0xf0, 0x4c, 0xb4, 0xf4, 0xad, 0xcb,
|
||||||
|
0xf0, 0xf0, 0xd3, 0xad, 0xbd, 0xf0, 0x38, 0xed, 0xcb, 0xf0, 0xb0, 0x3a, 0xa9, 0x00, 0x8d, 0xdf,
|
||||||
|
0xf0, 0xad, 0xca, 0xf0, 0xd0, 0x30, 0xee, 0xdf, 0xf0, 0xd0, 0x28, 0xce, 0xe0, 0xf0, 0xd0, 0x29,
|
||||||
|
0xad, 0xdf, 0xf0, 0xd0, 0x11, 0xee, 0xdf, 0xf0, 0xad, 0xcb, 0xf0, 0xd0, 0x02, 0xa9, 0x20, 0x8d,
|
||||||
|
0xe0, 0xf0, 0xa9, 0x00, 0xf0, 0x10, 0xce, 0xdf, 0xf0, 0xad, 0xca, 0xf0, 0xd0, 0x02, 0xa9, 0x20,
|
||||||
|
0x8d, 0xe0, 0xf0, 0xad, 0xcc, 0xf0, 0x8d, 0xbd, 0xf0, 0xa2, 0x00, 0xbd, 0xc3, 0xf0, 0xf0, 0x44,
|
||||||
|
0xa9, 0x00, 0x85, 0xff, 0xbc, 0xc0, 0xf0, 0xb9, 0xbd, 0xf0, 0xbc, 0xc6, 0xf0, 0xf0, 0x0e, 0x30,
|
||||||
|
0x08, 0x0a, 0x26, 0xff, 0x88, 0xd0, 0xfa, 0xf0, 0x04, 0x4a, 0xc8, 0xd0, 0xfc, 0xbc, 0xc3, 0xf0,
|
||||||
|
0x88, 0xd0, 0x0b, 0x9d, 0xcd, 0xf0, 0xa5, 0xff, 0x9d, 0xd0, 0xf0, 0x4c, 0x02, 0xf5, 0x88, 0xd0,
|
||||||
|
0x0b, 0x9d, 0xd3, 0xf0, 0xa5, 0xff, 0x9d, 0xd6, 0xf0, 0x4c, 0x02, 0xf5, 0x8d, 0xd9, 0xf0, 0xa5,
|
||||||
|
0xff, 0x8d, 0xdc, 0xf0, 0xe8, 0xe0, 0x03, 0xd0, 0xb2, 0xad, 0x00, 0xf0, 0x29, 0x7f, 0x8d, 0x00,
|
||||||
|
0xf0, 0xad, 0x56, 0xf1, 0x85, 0xfb, 0xad, 0x57, 0xf1, 0x85, 0xfc, 0xad, 0x58, 0xf1, 0x85, 0xfd,
|
||||||
|
0xad, 0x59, 0xf1, 0x85, 0xfe, 0xad, 0x5a, 0xf1, 0x85, 0xff, 0x6c, 0x5d, 0xf1, 0xbd, 0x60, 0xf0,
|
||||||
|
0xd0, 0x03, 0x4c, 0x9f, 0xf6, 0x4c, 0xba, 0xf5, 0xde, 0x30, 0xf0, 0xd0, 0x03, 0x4c, 0xa0, 0xf6,
|
||||||
|
0xbd, 0x36, 0xf0, 0x30, 0xe8, 0xd0, 0x1a, 0xbd, 0x3f, 0xf0, 0xf0, 0x05, 0xde, 0x3f, 0xf0, 0xd0,
|
||||||
|
0x10, 0xbd, 0x39, 0xf0, 0xdd, 0x30, 0xf0, 0x90, 0x08, 0xbd, 0x1a, 0xf0, 0x29, 0xfe, 0x9d, 0x1a,
|
||||||
|
0xf0, 0xbd, 0x42, 0xf0, 0xf0, 0x56, 0x0a, 0xbd, 0x0e, 0xf0, 0xb0, 0x1d, 0x7d, 0x45, 0xf0, 0x9d,
|
||||||
|
0x0e, 0xf0, 0xa8, 0xbd, 0x11, 0xf0, 0x7d, 0x48, 0xf0, 0x9d, 0x11, 0xf0, 0x48, 0x98, 0xdd, 0x8d,
|
||||||
|
0xf0, 0x68, 0xfd, 0x90, 0xf0, 0xb0, 0x1f, 0x90, 0x2e, 0xfd, 0x45, 0xf0, 0x9d, 0x0e, 0xf0, 0xbd,
|
||||||
|
0x11, 0xf0, 0xfd, 0x48, 0xf0, 0x9d, 0x11, 0xf0, 0xbd, 0x8d, 0xf0, 0xdd, 0x0e, 0xf0, 0xbd, 0x90,
|
||||||
|
0xf0, 0xfd, 0x11, 0xf0, 0x90, 0x11, 0xbd, 0x8d, 0xf0, 0x9d, 0x0e, 0xf0, 0xbd, 0x90, 0xf0, 0x9d,
|
||||||
|
0x11, 0xf0, 0xa9, 0x00, 0x9d, 0x42, 0xf0, 0xbd, 0x60, 0xf0, 0xf0, 0x55, 0xbd, 0x4b, 0xf0, 0xf0,
|
||||||
|
0x4b, 0xa0, 0x00, 0xde, 0x4e, 0xf0, 0xd0, 0x31, 0xbd, 0x51, 0xf0, 0x1d, 0x54, 0xf0, 0xd0, 0x1b,
|
||||||
|
0xbd, 0x5d, 0xf0, 0x9d, 0x57, 0xf0, 0x9d, 0x4e, 0xf0, 0xbd, 0x4b, 0xf0, 0x0a, 0xbd, 0x5a, 0xf0,
|
||||||
|
0x90, 0x04, 0x49, 0xff, 0x69, 0x00, 0x9d, 0x4b, 0xf0, 0xd0, 0x10, 0xbd, 0x57, 0xf0, 0x9d, 0x4e,
|
||||||
|
0xf0, 0x98, 0x38, 0xfd, 0x4b, 0xf0, 0x9d, 0x4b, 0xf0, 0xc9, 0x00, 0x10, 0x01, 0x88, 0x18, 0x7d,
|
||||||
|
0x51, 0xf0, 0x9d, 0x51, 0xf0, 0x98, 0x7d, 0x54, 0xf0, 0x9d, 0x54, 0xf0, 0xbd, 0x36, 0xf0, 0x30,
|
||||||
|
0x15, 0xbd, 0x93, 0xf0, 0xf0, 0x10, 0x18, 0x7d, 0x14, 0xf0, 0x9d, 0x14, 0xf0, 0xbd, 0x96, 0xf0,
|
||||||
|
0x7d, 0x17, 0xf0, 0x9d, 0x17, 0xf0, 0xbd, 0x63, 0xf0, 0xf0, 0x4b, 0xa0, 0x00, 0xde, 0x66, 0xf0,
|
||||||
|
0xd0, 0x31, 0xbd, 0x69, 0xf0, 0x1d, 0x6c, 0xf0, 0xd0, 0x1b, 0xbd, 0x72, 0xf0, 0x9d, 0x6f, 0xf0,
|
||||||
|
0x9d, 0x66, 0xf0, 0xbd, 0x63, 0xf0, 0x0a, 0xbd, 0x75, 0xf0, 0x90, 0x04, 0x49, 0xff, 0x69, 0x00,
|
||||||
|
0x9d, 0x63, 0xf0, 0xd0, 0x10, 0xbd, 0x6f, 0xf0, 0x9d, 0x66, 0xf0, 0x98, 0x38, 0xfd, 0x63, 0xf0,
|
||||||
|
0x9d, 0x63, 0xf0, 0xc9, 0x00, 0x10, 0x01, 0x88, 0x18, 0x7d, 0x69, 0xf0, 0x9d, 0x69, 0xf0, 0x98,
|
||||||
|
0x7d, 0x6c, 0xf0, 0x9d, 0x6c, 0xf0, 0xbd, 0x36, 0xf0, 0x10, 0x03, 0x4c, 0x9f, 0xf6, 0xa0, 0x00,
|
||||||
|
0xbd, 0xa2, 0xf0, 0xf0, 0x1c, 0x10, 0x01, 0xc8, 0x18, 0x6d, 0x23, 0xf0, 0x48, 0x29, 0x07, 0x8d,
|
||||||
|
0x23, 0xf0, 0x68, 0x6a, 0x4a, 0x4a, 0x18, 0x79, 0xa6, 0xf1, 0x18, 0x6d, 0x24, 0xf0, 0x8d, 0x24,
|
||||||
|
0xf0, 0x60, 0xbd, 0xa8, 0xf0, 0x85, 0xfd, 0xbd, 0xab, 0xf0, 0x85, 0xfe, 0xd0, 0x04, 0x60, 0x20,
|
||||||
|
0x98, 0xf8, 0xad, 0x00, 0xf0, 0x3d, 0x62, 0xf1, 0xf0, 0xf4, 0xa0, 0x00, 0xb1, 0xfd, 0x85, 0xff,
|
||||||
|
0xc8, 0xb1, 0xfd, 0xa8, 0xa5, 0xfd, 0x18, 0x69, 0x02, 0x85, 0xfd, 0x9d, 0xa8, 0xf0, 0xa5, 0xfe,
|
||||||
|
0x69, 0x00, 0x85, 0xfe, 0x9d, 0xab, 0xf0, 0xa5, 0xff, 0x29, 0x03, 0xd0, 0xd2, 0xbd, 0x8d, 0xf0,
|
||||||
|
0x9d, 0x0e, 0xf0, 0xbd, 0x90, 0xf0, 0x9d, 0x11, 0xf0, 0xa5, 0xff, 0x9d, 0x05, 0xf0, 0x98, 0x9d,
|
||||||
|
0x02, 0xf0, 0x29, 0x07, 0xa8, 0xb9, 0x67, 0xf1, 0x8d, 0x6f, 0xf1, 0xbd, 0x02, 0xf0, 0x29, 0x38,
|
||||||
|
0x4a, 0x4a, 0x4a, 0x7d, 0x81, 0xf0, 0x85, 0xfd, 0xbd, 0x02, 0xf0, 0x29, 0xc0, 0x0a, 0x2a, 0x2a,
|
||||||
|
0xa8, 0xb9, 0x6f, 0xf1, 0x85, 0xfe, 0xbd, 0x02, 0xf0, 0x29, 0x07, 0xf0, 0x62, 0xa8, 0xb9, 0x72,
|
||||||
|
0xf1, 0x65, 0xfe, 0x18, 0x7d, 0x84, 0xf0, 0x10, 0x05, 0x18, 0x69, 0x0c, 0xe6, 0xfd, 0xc9, 0x0c,
|
||||||
|
0x90, 0x04, 0xe9, 0x0c, 0xc6, 0xfd, 0x85, 0xfe, 0xa8, 0xb9, 0x86, 0xf1, 0x85, 0xff, 0xb9, 0x7a,
|
||||||
|
0xf1, 0xa4, 0xfd, 0x88, 0x30, 0x06, 0x46, 0xff, 0x6a, 0x88, 0x10, 0xfa, 0x18, 0x7d, 0x87, 0xf0,
|
||||||
|
0x9d, 0x8d, 0xf0, 0xa5, 0xff, 0x7d, 0x8a, 0xf0, 0x9d, 0x90, 0xf0, 0xbd, 0x05, 0xf0, 0xd0, 0x03,
|
||||||
|
0x4c, 0xa0, 0xf6, 0xbd, 0x45, 0xf0, 0x1d, 0x48, 0xf0, 0xf0, 0x16, 0xbd, 0x0e, 0xf0, 0xdd, 0x8d,
|
||||||
|
0xf0, 0xbd, 0x11, 0xf0, 0xfd, 0x90, 0xf0, 0xa9, 0xfe, 0x6a, 0x9d, 0x42, 0xf0, 0x90, 0x11, 0xf0,
|
||||||
|
0x4a, 0x9d, 0x42, 0xf0, 0xbd, 0x8d, 0xf0, 0x9d, 0x0e, 0xf0, 0xbd, 0x90, 0xf0, 0x9d, 0x11, 0xf0,
|
||||||
|
0xbd, 0x36, 0xf0, 0x0a, 0xd0, 0x35, 0xbd, 0x93, 0xf0, 0xf0, 0x0c, 0xbd, 0x99, 0xf0, 0x9d, 0x14,
|
||||||
|
0xf0, 0xbd, 0x9c, 0xf0, 0x9d, 0x17, 0xf0, 0xbd, 0x9f, 0xf0, 0xf0, 0x0f, 0xa4, 0xfd, 0x18, 0x79,
|
||||||
|
0x92, 0xf1, 0xa4, 0xfe, 0x18, 0x79, 0x9a, 0xf1, 0x18, 0x90, 0x08, 0xbd, 0xa2, 0xf0, 0xf0, 0x0b,
|
||||||
|
0xbd, 0xa5, 0xf0, 0x8d, 0x24, 0xf0, 0xa9, 0x00, 0x8d, 0x23, 0xf0, 0xbd, 0x3c, 0xf0, 0x9d, 0x3f,
|
||||||
|
0xf0, 0xbd, 0x05, 0xf0, 0x29, 0x40, 0x9d, 0x36, 0xf0, 0xbd, 0x05, 0xf0, 0x4a, 0x4a, 0x29, 0x07,
|
||||||
|
0xd0, 0x30, 0xbd, 0x05, 0xf0, 0x30, 0x14, 0xad, 0x27, 0xf0, 0x29, 0x3c, 0xd0, 0x1e, 0xad, 0x27,
|
||||||
|
0xf0, 0x0a, 0x2a, 0x2a, 0xd0, 0x02, 0xa9, 0x04, 0x4c, 0x70, 0xf8, 0xad, 0x28, 0xf0, 0xf0, 0x0c,
|
||||||
|
0x29, 0x3f, 0xd0, 0x08, 0xad, 0x28, 0xf0, 0x0a, 0x2a, 0x2a, 0xd0, 0x66, 0xa9, 0x10, 0x8d, 0x00,
|
||||||
|
0xf0, 0x60, 0xc9, 0x01, 0xd0, 0x13, 0xbd, 0x05, 0xf0, 0x29, 0x20, 0xd0, 0x06, 0xad, 0x29, 0xf0,
|
||||||
|
0x4c, 0x70, 0xf8, 0xbd, 0x2a, 0xf0, 0x4c, 0x70, 0xf8, 0xa8, 0xbd, 0x05, 0xf0, 0x29, 0xa0, 0xc9,
|
||||||
|
0x80, 0xf0, 0x30, 0x85, 0xff, 0x18, 0xad, 0x27, 0xf0, 0xd0, 0x01, 0x38, 0x88, 0x88, 0xf0, 0x06,
|
||||||
|
0x6a, 0xb0, 0x4e, 0x88, 0xd0, 0xfa, 0xa4, 0xff, 0x85, 0xff, 0xf0, 0x26, 0x46, 0xff, 0xb0, 0x41,
|
||||||
|
0xf0, 0x42, 0x65, 0xff, 0xb0, 0x3e, 0xc8, 0x10, 0x19, 0x46, 0xff, 0xb0, 0x34, 0x65, 0xff, 0x90,
|
||||||
|
0x11, 0xb0, 0x31, 0xad, 0x28, 0xf0, 0xf0, 0x29, 0x88, 0x88, 0xf0, 0x06, 0x4a, 0xb0, 0x22, 0x88,
|
||||||
|
0xd0, 0xfa, 0x9d, 0x30, 0xf0, 0xbd, 0x1a, 0xf0, 0x29, 0xf6, 0x9d, 0x1a, 0xf0, 0x38, 0xbd, 0x02,
|
||||||
|
0xf0, 0x29, 0x07, 0xd0, 0x03, 0x7e, 0x36, 0xf0, 0xbd, 0x1a, 0xf0, 0x69, 0x00, 0x9d, 0x1a, 0xf0,
|
||||||
|
0x60, 0xa9, 0x10, 0x2c, 0xa9, 0x18, 0x8d, 0x00, 0xf0, 0x60, 0x98, 0x48, 0xa5, 0xff, 0x4a, 0x90,
|
||||||
|
0x03, 0x4c, 0x42, 0xfa, 0x4a, 0x4a, 0xb0, 0x1e, 0x4a, 0xb0, 0x0e, 0x9d, 0x9c, 0xf0, 0x9d, 0x17,
|
||||||
|
0xf0, 0x68, 0x9d, 0x99, 0xf0, 0x9d, 0x14, 0xf0, 0x60, 0x4a, 0x90, 0x02, 0x09, 0xf8, 0x9d, 0x8a,
|
||||||
|
0xf0, 0x68, 0x9d, 0x87, 0xf0, 0x60, 0x4a, 0xb0, 0x03, 0x4c, 0x4a, 0xf9, 0x4a, 0xb0, 0x61, 0x4a,
|
||||||
|
0xb0, 0x0f, 0xd0, 0x08, 0x68, 0x9d, 0xa5, 0xf0, 0x8d, 0x24, 0xf0, 0x60, 0x68, 0x9d, 0x3c, 0xf0,
|
||||||
|
0x60, 0xd0, 0x48, 0x68, 0x9d, 0x7e, 0xf0, 0xc9, 0x5b, 0xf0, 0x33, 0xa8, 0x4a, 0x4a, 0x4a, 0x38,
|
||||||
|
0xe9, 0x0b, 0x18, 0x7d, 0x84, 0xf0, 0x30, 0x0c, 0xc9, 0x0c, 0x90, 0x11, 0xe9, 0x0c, 0xde, 0x81,
|
||||||
|
0xf0, 0x4c, 0x0b, 0xf9, 0xc9, 0xf5, 0xb0, 0x05, 0x69, 0x0c, 0xfe, 0x81, 0xf0, 0x9d, 0x84, 0xf0,
|
||||||
|
0x98, 0x29, 0x07, 0x38, 0xe9, 0x03, 0x18, 0x7d, 0x81, 0xf0, 0x9d, 0x81, 0xf0, 0x60, 0xbd, 0x78,
|
||||||
|
0xf0, 0x9d, 0x81, 0xf0, 0xbd, 0x7b, 0xf0, 0x9d, 0x84, 0xf0, 0x60, 0x68, 0x9d, 0xc6, 0xf0, 0x60,
|
||||||
|
0x4a, 0xb0, 0x08, 0x9d, 0x0b, 0xf0, 0x68, 0x9d, 0x08, 0xf0, 0x60, 0x4a, 0x6a, 0x6a, 0x6d, 0x5b,
|
||||||
|
0xf1, 0x8d, 0x2d, 0xf0, 0x68, 0x6d, 0x5c, 0xf1, 0x8d, 0x2e, 0xf0, 0x60, 0x4a, 0x90, 0x03, 0x4c,
|
||||||
|
0xd3, 0xf9, 0x4a, 0xb0, 0x40, 0x4a, 0xb0, 0x17, 0x4a, 0xb0, 0x0f, 0x68, 0x8d, 0x27, 0xf0, 0x4a,
|
||||||
|
0x4a, 0x4a, 0xa8, 0xb9, 0xaf, 0xf1, 0x8d, 0x28, 0xf0, 0x60, 0x68, 0x9d, 0x5d, 0xf0, 0x60, 0x4a,
|
||||||
|
0xb0, 0x05, 0x68, 0x8d, 0x01, 0xf0, 0x60, 0x68, 0xf0, 0x11, 0x9d, 0x75, 0xf0, 0xbc, 0x63, 0xf0,
|
||||||
|
0xd0, 0x08, 0x9d, 0x63, 0xf0, 0xa9, 0x01, 0x9d, 0x66, 0xf0, 0x60, 0x9d, 0x63, 0xf0, 0x9d, 0x69,
|
||||||
|
0xf0, 0x9d, 0x6c, 0xf0, 0x60, 0x4a, 0xb0, 0x30, 0x4a, 0xb0, 0x05, 0x68, 0x9d, 0x39, 0xf0, 0x60,
|
||||||
|
0x68, 0xa0, 0x00, 0x4a, 0x90, 0x02, 0xc8, 0x18, 0x48, 0x29, 0x07, 0x79, 0xac, 0xf1, 0x9d, 0x78,
|
||||||
|
0xf0, 0x9d, 0x81, 0xf0, 0x68, 0x4a, 0x4a, 0x4a, 0x18, 0x79, 0xad, 0xf1, 0x9d, 0x7b, 0xf0, 0x9d,
|
||||||
|
0x84, 0xf0, 0xa9, 0x5b, 0x9d, 0x7e, 0xf0, 0x60, 0x4a, 0xb0, 0x05, 0x68, 0x9d, 0xa2, 0xf0, 0x60,
|
||||||
|
0x68, 0x8d, 0xcc, 0xf0, 0x60, 0x4a, 0xb0, 0x27, 0x4a, 0xb0, 0x0d, 0x4a, 0xb0, 0x05, 0x68, 0x8d,
|
||||||
|
0x29, 0xf0, 0x60, 0x68, 0x9d, 0x9f, 0xf0, 0x60, 0x4a, 0xb0, 0x0f, 0x68, 0x9d, 0x93, 0xf0, 0xa0,
|
||||||
|
0x00, 0x0a, 0x90, 0x01, 0x88, 0x98, 0x9d, 0x96, 0xf0, 0x60, 0x68, 0x9d, 0x72, 0xf0, 0x60, 0x4a,
|
||||||
|
0xb0, 0x1c, 0x4a, 0xb0, 0x15, 0x68, 0x9d, 0xb7, 0xf0, 0xa5, 0xfd, 0x9d, 0xb1, 0xf0, 0xa5, 0xfe,
|
||||||
|
0x9d, 0xb4, 0xf0, 0xbd, 0x33, 0xf0, 0x9d, 0xae, 0xf0, 0x60, 0x68, 0x6c, 0x5f, 0xf1, 0x4a, 0xb0,
|
||||||
|
0x1e, 0x68, 0xd0, 0x0a, 0x9d, 0x4b, 0xf0, 0x9d, 0x51, 0xf0, 0x9d, 0x54, 0xf0, 0x60, 0x9d, 0x5a,
|
||||||
|
0xf0, 0xbc, 0x4b, 0xf0, 0xd0, 0x08, 0x9d, 0x4b, 0xf0, 0xa9, 0x01, 0x9d, 0x4e, 0xf0, 0x60, 0x68,
|
||||||
|
0x9d, 0x2a, 0xf0, 0x60, 0x4a, 0x90, 0x08, 0x9d, 0x48, 0xf0, 0x68, 0x9d, 0x45, 0xf0, 0x60, 0x68,
|
||||||
|
0x4a, 0xb0, 0x61, 0x4a, 0xb0, 0x25, 0x4a, 0xb0, 0x05, 0x4a, 0xa0, 0xf0, 0xd0, 0x06, 0x0a, 0x0a,
|
||||||
|
0x0a, 0x0a, 0xa0, 0x0f, 0x85, 0xff, 0x98, 0xb0, 0x09, 0x3d, 0x1d, 0xf0, 0x05, 0xff, 0x9d, 0x1d,
|
||||||
|
0xf0, 0x60, 0x3d, 0x20, 0xf0, 0x05, 0xff, 0x9d, 0x20, 0xf0, 0x60, 0x4a, 0xb0, 0x38, 0x4a, 0xb0,
|
||||||
|
0x64, 0x85, 0xff, 0xbd, 0xba, 0xf0, 0xdd, 0xa9, 0xf1, 0xf0, 0x54, 0xfe, 0xba, 0xf0, 0xa8, 0xa5,
|
||||||
|
0xfd, 0x99, 0xe1, 0xf0, 0xa5, 0xfe, 0x99, 0xf0, 0xf0, 0xbd, 0x33, 0xf0, 0x99, 0x2f, 0xf1, 0xa4,
|
||||||
|
0xff, 0xb9, 0x17, 0xf1, 0xf0, 0x36, 0x85, 0xfe, 0xb9, 0xff, 0xf0, 0x85, 0xfd, 0xb9, 0x3e, 0xf1,
|
||||||
|
0x9d, 0x33, 0xf0, 0x60, 0xb0, 0x4b, 0x4a, 0xb0, 0x3c, 0xa8, 0xa5, 0xfd, 0x99, 0xff, 0xf0, 0xa5,
|
||||||
|
0xfe, 0x99, 0x17, 0xf1, 0xbd, 0x33, 0xf0, 0x99, 0x3e, 0xf1, 0xbd, 0xba, 0xf0, 0xdd, 0xa9, 0xf1,
|
||||||
|
0xf0, 0x0d, 0xfe, 0xba, 0xf0, 0xa8, 0xa9, 0x00, 0x99, 0xf0, 0xf0, 0x60, 0xa9, 0x30, 0x2c, 0xa9,
|
||||||
|
0x28, 0x8d, 0x00, 0xf0, 0x60, 0x0a, 0x0a, 0x0a, 0x0a, 0x4d, 0x25, 0xf0, 0x29, 0xf0, 0x4d, 0x25,
|
||||||
|
0xf0, 0x8d, 0x25, 0xf0, 0x60, 0x4d, 0x26, 0xf0, 0x29, 0x0f, 0x4d, 0x26, 0xf0, 0x8d, 0x26, 0xf0,
|
||||||
|
0x60, 0x4a, 0xb0, 0x0b, 0x4a, 0xb0, 0x04, 0x8d, 0xca, 0xf0, 0x60, 0x8d, 0xcb, 0xf0, 0x60, 0x4a,
|
||||||
|
0x90, 0x03, 0x4c, 0xa5, 0xfb, 0x4a, 0xa8, 0xf0, 0x21, 0x88, 0xf0, 0x34, 0x88, 0xf0, 0x42, 0x88,
|
||||||
|
0xf0, 0x4a, 0x88, 0xf0, 0x52, 0x88, 0xf0, 0x5c, 0x88, 0xf0, 0x66, 0x88, 0xf0, 0x73, 0x29, 0x07,
|
||||||
|
0x09, 0x10, 0xb0, 0x03, 0x4c, 0xb7, 0xfa, 0x4c, 0x7f, 0xfa, 0xac, 0x26, 0xf0, 0xb0, 0x07, 0xc8,
|
||||||
|
0x98, 0x29, 0x0f, 0xd0, 0x07, 0x60, 0x98, 0x29, 0x0f, 0xf0, 0x04, 0x88, 0x8c, 0x26, 0xf0, 0x60,
|
||||||
|
0xbd, 0x62, 0xf1, 0x49, 0xff, 0x2d, 0x25, 0xf0, 0x90, 0x03, 0x1d, 0x62, 0xf1, 0x8d, 0x25, 0xf0,
|
||||||
|
0x60, 0xbd, 0x1a, 0xf0, 0x29, 0xfb, 0x90, 0x55, 0x09, 0x04, 0xb0, 0x51, 0xbd, 0x1a, 0xf0, 0x29,
|
||||||
|
0xfd, 0x90, 0x4a, 0x09, 0x02, 0xb0, 0x46, 0xad, 0x25, 0xf0, 0x29, 0xf7, 0x90, 0x02, 0x09, 0x08,
|
||||||
|
0x8d, 0x25, 0xf0, 0x60, 0xad, 0x26, 0xf0, 0x29, 0x7f, 0x90, 0x02, 0x09, 0x80, 0x8d, 0x26, 0xf0,
|
||||||
|
0x60, 0x98, 0x8d, 0xbd, 0xf0, 0x8d, 0xdf, 0xf0, 0xc8, 0x8c, 0xe0, 0xf0, 0x2a, 0x8d, 0xc9, 0xf0,
|
||||||
|
0x60, 0x98, 0x2a, 0x9d, 0x60, 0xf0, 0x60, 0x4a, 0xb0, 0x27, 0x4a, 0xb0, 0x14, 0xd0, 0x02, 0xa9,
|
||||||
|
0x08, 0x0a, 0x0a, 0x0a, 0x0a, 0x5d, 0x1a, 0xf0, 0x29, 0xf0, 0x5d, 0x1a, 0xf0, 0x9d, 0x1a, 0xf0,
|
||||||
|
0x60, 0x0a, 0x0a, 0x0a, 0x0a, 0x4d, 0x26, 0xf0, 0x29, 0x70, 0x4d, 0x26, 0xf0, 0x8d, 0x26, 0xf0,
|
||||||
|
0x60, 0x4a, 0x90, 0x04, 0x9d, 0xc0, 0xf0, 0x60, 0xa8, 0xf0, 0x20, 0x88, 0xf0, 0x40, 0x88, 0xf0,
|
||||||
|
0x63, 0x29, 0x03, 0x9d, 0xc3, 0xf0, 0xa9, 0x00, 0x9d, 0xcd, 0xf0, 0x9d, 0xd0, 0xf0, 0x9d, 0xd3,
|
||||||
|
0xf0, 0x9d, 0xd6, 0xf0, 0x8d, 0xd9, 0xf0, 0x8d, 0xdc, 0xf0, 0x60, 0xbd, 0xb7, 0xf0, 0xf0, 0x05,
|
||||||
|
0xde, 0xb7, 0xf0, 0xf0, 0x12, 0xbd, 0x33, 0xf0, 0xdd, 0xae, 0xf0, 0xd0, 0x0b, 0xbd, 0xb1, 0xf0,
|
||||||
|
0x85, 0xfd, 0xbd, 0xb4, 0xf0, 0x85, 0xfe, 0x60, 0xa9, 0x38, 0x8d, 0x00, 0xf0, 0x60, 0xbd, 0xba,
|
||||||
|
0xf0, 0xdd, 0xa8, 0xf1, 0xf0, 0x18, 0xde, 0xba, 0xf0, 0xa8, 0x88, 0xb9, 0xf0, 0xf0, 0xf0, 0x0d,
|
||||||
|
0x85, 0xfe, 0xb9, 0xe1, 0xf0, 0x85, 0xfd, 0xb9, 0x2f, 0xf1, 0x9d, 0x33, 0xf0, 0x60, 0xa9, 0x20,
|
||||||
|
0x8d, 0x00, 0xf0, 0x60, 0xad, 0x00, 0xf0, 0x5d, 0x62, 0xf1, 0x8d, 0x00, 0xf0, 0xa9, 0x01, 0x9d,
|
||||||
|
0x30, 0xf0, 0x60, 0xad, 0x00, 0xf0, 0x29, 0x07, 0x8d, 0x81, 0xfc, 0xd0, 0x03, 0x20, 0xe9, 0xf2,
|
||||||
|
0x60, 0x00, 0xa2, 0x51, 0xa0, 0xfc, 0x8e, 0x5d, 0xf1, 0x8c, 0x5e, 0xf1, 0x20, 0xcf, 0xf1, 0xa2,
|
||||||
|
0x00, 0xa0, 0x09, 0x20, 0x00, 0xf2, 0xa9, 0x07, 0x8d, 0x00, 0xf0, 0x8d, 0x81, 0xfc, 0x60, 0x00,
|
||||||
|
0x00, 0x00, 0xa9, 0x00, 0x29, 0xff, 0xf0, 0xf6, 0x4c, 0x29, 0xf3, 0xa9, 0x07, 0x8d, 0x00, 0xf0,
|
||||||
|
0x60, 0x00, 0x20, 0x60, 0xec, 0x4c, 0x60, 0xfc, 0x20, 0x80, 0xec, 0x4c, 0x80, 0xfc
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2012-2014 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
* Copyright 2010 Antti Lankila
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NULLSID_H
|
||||||
|
#define NULLSID_H
|
||||||
|
|
||||||
|
#include "c64/c64sid.h"
|
||||||
|
|
||||||
|
#include "sidcxx11.h"
|
||||||
|
|
||||||
|
namespace libsidplayfp
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SID chip placeholder which does nothing and returns 0xff on reading.
|
||||||
|
*/
|
||||||
|
class NullSid : public c64sid
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
NullSid() {}
|
||||||
|
virtual ~NullSid() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Returns singleton instance.
|
||||||
|
*/
|
||||||
|
static NullSid *getInstance()
|
||||||
|
{
|
||||||
|
static NullSid nullsid;
|
||||||
|
return &nullsid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(uint8_t) override {}
|
||||||
|
|
||||||
|
void write(uint_least8_t, uint8_t) override {}
|
||||||
|
uint8_t read(uint_least8_t) override { return 0xff; }
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // NULLSID_H
|
|
@ -0,0 +1,120 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import struct, sys, wave
|
||||||
|
|
||||||
|
class UnsupportedWaveformat(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class InvalidArgs(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class AnalysisError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def split_wave(input, pattern, multiplier=8):
|
||||||
|
wv = wave.open(input, 'r')
|
||||||
|
|
||||||
|
if wv.getnchannels() != 1:
|
||||||
|
raise UnsupportedWaveformat, "mono audio only"
|
||||||
|
if wv.getsampwidth() != 2:
|
||||||
|
raise UnsupportedWaveformat, "16-bit pcm only"
|
||||||
|
|
||||||
|
readlen = 128
|
||||||
|
|
||||||
|
outhandle = None
|
||||||
|
seqnum = -1
|
||||||
|
frames = None
|
||||||
|
sum = 0
|
||||||
|
|
||||||
|
# highpass filter
|
||||||
|
levelcomp_coeff = (50 * 2 * 3.14159) / wv.getframerate()
|
||||||
|
levelcomp = 0
|
||||||
|
pos = 0
|
||||||
|
while True:
|
||||||
|
# read in chunks, classify as silence or as signal
|
||||||
|
datachar = wv.readframes(readlen)
|
||||||
|
pos += readlen
|
||||||
|
|
||||||
|
if frames is not None:
|
||||||
|
frames += readlen
|
||||||
|
|
||||||
|
# wave finish?
|
||||||
|
if len(datachar) < readlen * 2:
|
||||||
|
if outhandle is not None:
|
||||||
|
outhandle.writeframes(datachar)
|
||||||
|
outhandle.close();
|
||||||
|
cliplen = float(frames) / outhandle.getframerate()
|
||||||
|
print "End writing wave %d, %.1f s clip" % (seqnum, cliplen)
|
||||||
|
outhandle = None
|
||||||
|
break
|
||||||
|
|
||||||
|
# get wave values
|
||||||
|
datatuple = struct.unpack("%sh" % readlen, datachar)
|
||||||
|
|
||||||
|
# analyse signal levels.
|
||||||
|
_sum = 0
|
||||||
|
_min = 0
|
||||||
|
_max = 0
|
||||||
|
for _ in datatuple:
|
||||||
|
_ /= 32768.
|
||||||
|
if _ < _min:
|
||||||
|
_min = _
|
||||||
|
if _ > _max:
|
||||||
|
_max = _
|
||||||
|
levelcomp = _ * levelcomp_coeff + (1 - levelcomp_coeff) * levelcomp
|
||||||
|
_sum += (_ - levelcomp) ** 2
|
||||||
|
_sum /= readlen
|
||||||
|
sum = (sum * 15 + _sum) / 16;
|
||||||
|
|
||||||
|
start = _max > 0.2# or sum > 5e-7
|
||||||
|
end = _min < -0.2# or sum < 1e-7
|
||||||
|
|
||||||
|
# trigger silence
|
||||||
|
if end:
|
||||||
|
if outhandle is not None:
|
||||||
|
outhandle.close()
|
||||||
|
cliplen = float(frames) / outhandle.getframerate()
|
||||||
|
print "End writing wave %d, %.1f seconds" % (seqnum, cliplen)
|
||||||
|
if cliplen < 4:
|
||||||
|
raise AnalysisError, "sound prematurely clipped at %f" % (pos/outhandle.getframerate())
|
||||||
|
if cliplen > 6:
|
||||||
|
raise AnalysisError, "sound clipped too late at %f" % (pos/outhandle.getframerate())
|
||||||
|
outhandle = None
|
||||||
|
frames = 0
|
||||||
|
|
||||||
|
# trigger signal
|
||||||
|
if start:
|
||||||
|
if outhandle is None:
|
||||||
|
seqnum += 1
|
||||||
|
|
||||||
|
outhandle = wave.open(pattern % (multiplier * seqnum), "w")
|
||||||
|
outhandle.setnchannels(1)
|
||||||
|
outhandle.setframerate(wv.getframerate())
|
||||||
|
outhandle.setsampwidth(2);
|
||||||
|
|
||||||
|
if frames is not None:
|
||||||
|
cliplen = float(frames) / outhandle.getframerate()
|
||||||
|
print "Begun writing wave %d after %.1f s silence" % (seqnum, cliplen)
|
||||||
|
if cliplen < 0.05:
|
||||||
|
raise AnalysisError, "silence too short";
|
||||||
|
if cliplen > 1.5:
|
||||||
|
raise AnalysisError, "silence too long";
|
||||||
|
|
||||||
|
frames = 0
|
||||||
|
continue
|
||||||
|
|
||||||
|
# write if we got handle
|
||||||
|
if outhandle is not None:
|
||||||
|
outhandle.writeframes(datachar)
|
||||||
|
|
||||||
|
if seqnum != 2048 / multiplier - 1:
|
||||||
|
raise AnalysisError, "Wrong count of waves written. Results are probably invalid."
|
||||||
|
|
||||||
|
def main(args):
|
||||||
|
if len(args) != 2:
|
||||||
|
raise InvalidArgs, "Usage: program <inputfile> { lp | hp }"
|
||||||
|
return split_wave(args[0], args[1] + "_%04d.wav")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main(sys.argv[1:])
|
|
@ -0,0 +1,470 @@
|
||||||
|
/*
|
||||||
|
* This file is part of sidplayfp, a console SID player.
|
||||||
|
*
|
||||||
|
* Copyright 2011-2014 Leandro Nini
|
||||||
|
* Copyright 2000-2001 Simon White
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "IniConfig.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cerrno>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
# include <sys/types.h>
|
||||||
|
# include <sys/stat.h> /* mkdir */
|
||||||
|
# include <dirent.h> /* opendir */
|
||||||
|
#else
|
||||||
|
# include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
#include "ini/dataParser.h"
|
||||||
|
|
||||||
|
void debug(const TCHAR *msg)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
SID_COUT << msg << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
const TCHAR *IniConfig::DIR_NAME = TEXT("sidplayfp");
|
||||||
|
const TCHAR *IniConfig::FILE_NAME = TEXT("sidplayfp.ini");
|
||||||
|
|
||||||
|
#define SAFE_FREE(p) { if(p) { free (p); (p)=NULL; } }
|
||||||
|
|
||||||
|
IniConfig::IniConfig() :
|
||||||
|
status(true)
|
||||||
|
{ // Initialise everything else
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IniConfig::~IniConfig()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IniConfig::clear()
|
||||||
|
{
|
||||||
|
sidplay2_s.version = 1; // INI File Version
|
||||||
|
sidplay2_s.database.clear();
|
||||||
|
sidplay2_s.playLength = 0; // INFINITE
|
||||||
|
sidplay2_s.recordLength = 3 * 60 + 30; // 3.5 minutes
|
||||||
|
sidplay2_s.kernalRom.clear();
|
||||||
|
sidplay2_s.basicRom.clear();
|
||||||
|
sidplay2_s.chargenRom.clear();
|
||||||
|
|
||||||
|
console_s.ansi = false;
|
||||||
|
console_s.topLeft = '+';
|
||||||
|
console_s.topRight = '+';
|
||||||
|
console_s.bottomLeft = '+';
|
||||||
|
console_s.bottomRight = '+';
|
||||||
|
console_s.vertical = '|';
|
||||||
|
console_s.horizontal = '-';
|
||||||
|
console_s.junctionLeft = '+';
|
||||||
|
console_s.junctionRight = '+';
|
||||||
|
|
||||||
|
audio_s.frequency = SidConfig::DEFAULT_SAMPLING_FREQ;
|
||||||
|
audio_s.playback = SidConfig::MONO;
|
||||||
|
audio_s.precision = 16;
|
||||||
|
|
||||||
|
emulation_s.modelDefault = SidConfig::PAL;
|
||||||
|
emulation_s.modelForced = false;
|
||||||
|
emulation_s.sidModel = SidConfig::MOS6581;
|
||||||
|
emulation_s.forceModel = false;
|
||||||
|
emulation_s.filter = true;
|
||||||
|
emulation_s.engine.clear();
|
||||||
|
|
||||||
|
emulation_s.bias = 0.0;
|
||||||
|
emulation_s.filterCurve6581 = 0.0;
|
||||||
|
emulation_s.filterCurve8580 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IniConfig::readDouble(iniHandler &ini, const TCHAR *key, double &result)
|
||||||
|
{
|
||||||
|
const TCHAR* value = ini.getValue(key);
|
||||||
|
if (value == 0)
|
||||||
|
{ // Doesn't exist, add it
|
||||||
|
ini.addValue(key, TEXT(""));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = dataParser::parseDouble(value);
|
||||||
|
}
|
||||||
|
catch (dataParser::parseError const &e)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IniConfig::readInt(iniHandler &ini, const TCHAR *key, int &result)
|
||||||
|
{
|
||||||
|
const TCHAR* value = ini.getValue(key);
|
||||||
|
if (value == 0)
|
||||||
|
{ // Doesn't exist, add it
|
||||||
|
ini.addValue(key, TEXT(""));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = dataParser::parseInt(value);
|
||||||
|
}
|
||||||
|
catch (dataParser::parseError const &e)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IniConfig::readString(iniHandler &ini, const TCHAR *key, SID_STRING &result)
|
||||||
|
{
|
||||||
|
const TCHAR* value = ini.getValue(key);
|
||||||
|
if (value == 0)
|
||||||
|
{ // Doesn't exist, add it
|
||||||
|
ini.addValue(key, TEXT(""));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.assign(value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IniConfig::readBool(iniHandler &ini, const TCHAR *key, bool &result)
|
||||||
|
{
|
||||||
|
const TCHAR* value = ini.getValue(key);
|
||||||
|
if (value == 0)
|
||||||
|
{ // Doesn't exist, add it
|
||||||
|
ini.addValue(key, TEXT(""));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = dataParser::parseBool(value);
|
||||||
|
}
|
||||||
|
catch (dataParser::parseError const &e)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IniConfig::readChar(iniHandler &ini, const TCHAR *key, char &ch)
|
||||||
|
{
|
||||||
|
SID_STRING str;
|
||||||
|
bool ret = readString(ini, key, str);
|
||||||
|
if (!ret)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
TCHAR c = 0;
|
||||||
|
|
||||||
|
// Check if we have an actual chanracter
|
||||||
|
if (str[0] == '\'')
|
||||||
|
{
|
||||||
|
if (str[2] != '\'')
|
||||||
|
ret = false;
|
||||||
|
else
|
||||||
|
c = str[1];
|
||||||
|
} // Nope is number
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
c = dataParser::parseInt(str.c_str());
|
||||||
|
}
|
||||||
|
catch (dataParser::parseError const &e)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clip off special characters
|
||||||
|
if ((unsigned) c >= 32)
|
||||||
|
ch = c;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IniConfig::readTime(iniHandler &ini, const TCHAR *key, int &value)
|
||||||
|
{
|
||||||
|
SID_STRING str;
|
||||||
|
bool ret = readString(ini, key, str);
|
||||||
|
if (!ret)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int time;
|
||||||
|
size_t sep = str.find_first_of(':');
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (sep == SID_STRING::npos)
|
||||||
|
{ // User gave seconds
|
||||||
|
time = dataParser::parseInt(str.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // Read in MM:SS format
|
||||||
|
str.replace(sep, 1, '\0');
|
||||||
|
int val = dataParser::parseInt(str.c_str());
|
||||||
|
if (val < 0 || val > 99)
|
||||||
|
goto IniCofig_readTime_error;
|
||||||
|
time = val * 60;
|
||||||
|
val = dataParser::parseInt(str.c_str()+sep + 1);
|
||||||
|
if (val < 0 || val > 59)
|
||||||
|
goto IniCofig_readTime_error;
|
||||||
|
time += val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (dataParser::parseError const &e)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = time;
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
IniCofig_readTime_error:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IniConfig::readSidplay2(iniHandler &ini)
|
||||||
|
{
|
||||||
|
if (!ini.setSection(TEXT("SIDPlayfp")))
|
||||||
|
ini.addSection(TEXT("SIDPlayfp"));
|
||||||
|
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
|
int version = sidplay2_s.version;
|
||||||
|
ret &= readInt (ini, TEXT("Version"), version);
|
||||||
|
if (version > 0)
|
||||||
|
sidplay2_s.version = version;
|
||||||
|
|
||||||
|
ret &= readString(ini, TEXT("Songlength Database"), sidplay2_s.database);
|
||||||
|
|
||||||
|
#if !defined _WIN32 && defined HAVE_UNISTD_H
|
||||||
|
if (sidplay2_s.database.empty())
|
||||||
|
{
|
||||||
|
char buffer[PATH_MAX];
|
||||||
|
snprintf(buffer, PATH_MAX, "%sSonglengths.txt", PKGDATADIR);
|
||||||
|
if (::access(buffer, R_OK) == 0)
|
||||||
|
sidplay2_s.database.assign(buffer);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int time;
|
||||||
|
if (readTime (ini, TEXT("Default Play Length"), time))
|
||||||
|
sidplay2_s.playLength = (uint_least32_t) time;
|
||||||
|
if (readTime (ini, TEXT("Default Record Length"), time))
|
||||||
|
sidplay2_s.recordLength = (uint_least32_t) time;
|
||||||
|
|
||||||
|
ret &= readString(ini, TEXT("Kernal Rom"), sidplay2_s.kernalRom);
|
||||||
|
ret &= readString(ini, TEXT("Basic Rom"), sidplay2_s.basicRom);
|
||||||
|
ret &= readString(ini, TEXT("Chargen Rom"), sidplay2_s.chargenRom);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IniConfig::readConsole(iniHandler &ini)
|
||||||
|
{
|
||||||
|
if (!ini.setSection (TEXT("Console")))
|
||||||
|
ini.addSection(TEXT("Console"));
|
||||||
|
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
|
ret &= readBool (ini, TEXT("Ansi"), console_s.ansi);
|
||||||
|
ret &= readChar (ini, TEXT("Char Top Left"), console_s.topLeft);
|
||||||
|
ret &= readChar (ini, TEXT("Char Top Right"), console_s.topRight);
|
||||||
|
ret &= readChar (ini, TEXT("Char Bottom Left"), console_s.bottomLeft);
|
||||||
|
ret &= readChar (ini, TEXT("Char Bottom Right"), console_s.bottomRight);
|
||||||
|
ret &= readChar (ini, TEXT("Char Vertical"), console_s.vertical);
|
||||||
|
ret &= readChar (ini, TEXT("Char Horizontal"), console_s.horizontal);
|
||||||
|
ret &= readChar (ini, TEXT("Char Junction Left"), console_s.junctionLeft);
|
||||||
|
ret &= readChar (ini, TEXT("Char Junction Right"), console_s.junctionRight);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IniConfig::readAudio(iniHandler &ini)
|
||||||
|
{
|
||||||
|
if (!ini.setSection (TEXT("Audio")))
|
||||||
|
ini.addSection(TEXT("Audio"));
|
||||||
|
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
|
{
|
||||||
|
int frequency = (int) audio_s.frequency;
|
||||||
|
ret &= readInt (ini, TEXT("Frequency"), frequency);
|
||||||
|
audio_s.frequency = (unsigned long) frequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int channels = 0;
|
||||||
|
ret &= readInt (ini, TEXT("Channels"), channels);
|
||||||
|
if (channels)
|
||||||
|
{
|
||||||
|
audio_s.playback = (channels == 1) ? SidConfig::MONO : SidConfig::STEREO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret &= readInt (ini, TEXT("BitsPerSample"), audio_s.precision);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IniConfig::readEmulation(iniHandler &ini)
|
||||||
|
{
|
||||||
|
if (!ini.setSection (TEXT("Emulation")))
|
||||||
|
ini.addSection(TEXT("Emulation"));
|
||||||
|
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
|
ret &= readString (ini, TEXT("Engine"), emulation_s.engine);
|
||||||
|
|
||||||
|
{
|
||||||
|
SID_STRING str;
|
||||||
|
const bool res = readString (ini, TEXT("C64Model"), str);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
if (str.compare(TEXT("PAL")) == 0)
|
||||||
|
emulation_s.modelDefault = SidConfig::PAL;
|
||||||
|
else if (str.compare(TEXT("NTSC")) == 0)
|
||||||
|
emulation_s.modelDefault = SidConfig::NTSC;
|
||||||
|
else if (str.compare(TEXT("OLD_NTSC")) == 0)
|
||||||
|
emulation_s.modelDefault = SidConfig::OLD_NTSC;
|
||||||
|
else if (str.compare(TEXT("DREAN")) == 0)
|
||||||
|
emulation_s.modelDefault = SidConfig::DREAN;
|
||||||
|
}
|
||||||
|
ret &= res;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret &= readBool (ini, TEXT("ForceC64Model"), emulation_s.modelForced);
|
||||||
|
|
||||||
|
{
|
||||||
|
SID_STRING str;
|
||||||
|
const bool res = readString (ini, TEXT("SidModel"), str);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
if (str.compare(TEXT("MOS6581")) == 0)
|
||||||
|
emulation_s.sidModel = SidConfig::MOS6581;
|
||||||
|
else if (str.compare(TEXT("MOS8580")) == 0)
|
||||||
|
emulation_s.sidModel = SidConfig::MOS8580;
|
||||||
|
}
|
||||||
|
ret &= res;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret &= readBool (ini, TEXT("ForceSidModel"), emulation_s.forceModel);
|
||||||
|
|
||||||
|
ret &= readBool (ini, TEXT("UseFilter"), emulation_s.filter);
|
||||||
|
|
||||||
|
ret &= readDouble (ini, TEXT("FilterBias"), emulation_s.bias);
|
||||||
|
ret &= readDouble (ini, TEXT("FilterCurve6581"), emulation_s.filterCurve6581);
|
||||||
|
ret &= readInt (ini, TEXT("FilterCurve8580"), emulation_s.filterCurve8580);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IniConfig::read()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
status = false;
|
||||||
|
|
||||||
|
SID_STRING configPath;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
configPath = utils::getConfigPath();
|
||||||
|
}
|
||||||
|
catch (utils::error const &e)
|
||||||
|
{
|
||||||
|
debug(TEXT("Cannot get config path!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
configPath.append(SEPARATOR).append(DIR_NAME);
|
||||||
|
|
||||||
|
// Make sure the config path exists
|
||||||
|
#ifndef _WIN32
|
||||||
|
if (!opendir(configPath.c_str()))
|
||||||
|
{
|
||||||
|
if (mkdir(configPath.c_str(), 0755) < 0)
|
||||||
|
{
|
||||||
|
debug(strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (GetFileAttributes(configPath.c_str()) == INVALID_FILE_ATTRIBUTES)
|
||||||
|
{
|
||||||
|
if (CreateDirectory(configPath.c_str(), NULL) == 0)
|
||||||
|
{
|
||||||
|
LPTSTR pBuffer;
|
||||||
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&pBuffer, 0, NULL);
|
||||||
|
debug(pBuffer);
|
||||||
|
LocalFree(pBuffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
configPath.append(SEPARATOR).append(FILE_NAME);
|
||||||
|
|
||||||
|
//debug(configPath.c_str());
|
||||||
|
|
||||||
|
iniHandler ini;
|
||||||
|
|
||||||
|
// Opens an existing file or creates a new one
|
||||||
|
if (!ini.open(configPath.c_str()))
|
||||||
|
{
|
||||||
|
debug(TEXT("Error reading config file!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = true;
|
||||||
|
status &= readSidplay2 (ini);
|
||||||
|
status &= readConsole (ini);
|
||||||
|
status &= readAudio (ini);
|
||||||
|
status &= readEmulation (ini);
|
||||||
|
ini.close();
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,96 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import os, sys, math, glob
|
||||||
|
|
||||||
|
def read_xy_file(filename, offset):
|
||||||
|
f = file(filename)
|
||||||
|
vals = []
|
||||||
|
for line in f:
|
||||||
|
x, y = line.split()
|
||||||
|
x = float(x)
|
||||||
|
y = float(y)
|
||||||
|
vals.append([x, y + offset(x, y)])
|
||||||
|
return vals
|
||||||
|
|
||||||
|
def main():
|
||||||
|
fftdir = sys.argv[1]
|
||||||
|
fnlp = "%s/lp_%%04d.wav.fft" % fftdir
|
||||||
|
fnhp = "%s/hp_%%04d.wav.fft" % fftdir
|
||||||
|
|
||||||
|
cutoffs = [];
|
||||||
|
for x in range(0, 2047):
|
||||||
|
if not os.path.exists(fnlp % x):
|
||||||
|
continue
|
||||||
|
cutoffs.append(x)
|
||||||
|
|
||||||
|
result = []
|
||||||
|
for cf in cutoffs:
|
||||||
|
|
||||||
|
# no correction function, but we should also dump
|
||||||
|
# the difference between lp and hp.
|
||||||
|
lp = read_xy_file(fnlp % cf, lambda x, y: 0)
|
||||||
|
hp = read_xy_file(fnhp % cf, lambda x, y: 0)
|
||||||
|
|
||||||
|
noise_threshold = 3
|
||||||
|
cf_est = 0
|
||||||
|
cf_n = 0
|
||||||
|
|
||||||
|
lens = range(len(lp))
|
||||||
|
for i in lens:
|
||||||
|
if lp[i][0] != hp[i][0]:
|
||||||
|
raise RuntimeError, "invalid content in cf %d" % cf
|
||||||
|
|
||||||
|
# zrx has a weird chip with freq ~ 140 Hz!
|
||||||
|
if lp[i][0] < 120 or lp[i][0] > 20000:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# disregard video signal spikes and some side spikes, unknown
|
||||||
|
# origin... the 4900 Hz spike seems to multiply
|
||||||
|
if lp[i][0] > 4500 and lp[i][0] < 4600:
|
||||||
|
continue
|
||||||
|
if lp[i][0] > 4800 and lp[i][0] < 4900:
|
||||||
|
continue
|
||||||
|
if lp[i][0] > 6650 and lp[i][0] < 6750:
|
||||||
|
continue
|
||||||
|
if lp[i][0] > 9740 and lp[i][0] < 9860:
|
||||||
|
continue
|
||||||
|
if lp[i][0] > 15600 and lp[i][0] < 15800:
|
||||||
|
continue
|
||||||
|
if lp[i][0] > 19500 and lp[i][0] < 19650:
|
||||||
|
continue
|
||||||
|
if lp[i][0] > 20150 and lp[i][0] < 20250:
|
||||||
|
continue
|
||||||
|
if lp[i][0] > 10050 and lp[i][0] < 10150:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if abs(lp[i][1] - hp[i][1]) > noise_threshold:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# this is ad-hoc weighing method. The values closer to crossing
|
||||||
|
# point get more weight. The right model might be logarithmic, not ** 2.
|
||||||
|
weight = noise_threshold - abs(lp[i][1] - hp[i][1]);
|
||||||
|
weight = weight ** 2
|
||||||
|
cf_est += weight * lp[i][0];
|
||||||
|
cf_n += weight;
|
||||||
|
|
||||||
|
# dump average
|
||||||
|
if cf_n == 0:
|
||||||
|
cf_n = 1
|
||||||
|
source = "%d,%d" % (cf, cf_est / cf_n)
|
||||||
|
result.append(source)
|
||||||
|
|
||||||
|
for i in range(len(result)):
|
||||||
|
print result[i].replace(",", " ")
|
||||||
|
return
|
||||||
|
|
||||||
|
print "[FilterMeasurement]"
|
||||||
|
print "type=1"
|
||||||
|
print "points=%d" % len(result)
|
||||||
|
for i in range(len(result)):
|
||||||
|
print "point%d=%s" % (i+1, result[i])
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011-2014 Leandro Nini
|
||||||
|
* Copyright (C) 2009 Antti S. Lankila
|
||||||
|
* Copyright (C) 2001 Simon White
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "EventScheduler.h"
|
||||||
|
|
||||||
|
|
||||||
|
void EventScheduler::reset()
|
||||||
|
{
|
||||||
|
firstEvent = nullptr;
|
||||||
|
currentTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventScheduler::cancel(Event &event)
|
||||||
|
{
|
||||||
|
Event **scan = &firstEvent;
|
||||||
|
|
||||||
|
while (*scan != nullptr)
|
||||||
|
{
|
||||||
|
if (&event == *scan)
|
||||||
|
{
|
||||||
|
*scan = (*scan)->next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
scan = &((*scan)->next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EventScheduler::isPending(Event &event) const
|
||||||
|
{
|
||||||
|
Event *scan = firstEvent;
|
||||||
|
while (scan != nullptr)
|
||||||
|
{
|
||||||
|
if (&event == scan)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
scan = scan->next;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,687 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2011-2014 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
* Copyright 2009-2014 VICE Project
|
||||||
|
* Copyright 2007-2010 Antti Lankila
|
||||||
|
* Copyright 2001 Simon White
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// References below are from:
|
||||||
|
// The MOS 6567/6569 video controller (VIC-II)
|
||||||
|
// and its application in the Commodore 64
|
||||||
|
// http://www.uni-mainz.de/~bauec002/VIC-Article.gz
|
||||||
|
|
||||||
|
#include "mos656x.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "sidendian.h"
|
||||||
|
|
||||||
|
namespace libsidplayfp
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Cycle # at which the VIC takes the bus in a bad line (BA goes low).
|
||||||
|
const unsigned int VICII_FETCH_CYCLE = 11;
|
||||||
|
|
||||||
|
const unsigned int VICII_SCREEN_TEXTCOLS = 40;
|
||||||
|
|
||||||
|
const MOS656X::model_data_t MOS656X::modelData[] =
|
||||||
|
{
|
||||||
|
{262, 64, &MOS656X::clockOldNTSC}, // Old NTSC
|
||||||
|
{263, 65, &MOS656X::clockNTSC}, // NTSC-M
|
||||||
|
{312, 63, &MOS656X::clockPAL}, // PAL-B
|
||||||
|
{312, 65, &MOS656X::clockNTSC}, // PAL-N
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *MOS656X::credit =
|
||||||
|
{
|
||||||
|
"MOS6567/6569/6572 (VIC II) Emulation:\n"
|
||||||
|
"\tCopyright (C) 2001 Simon White\n"
|
||||||
|
"\tCopyright (C) 2007-2010 Antti Lankila\n"
|
||||||
|
"\tCopyright (C) 2009-2014 VICE Project\n"
|
||||||
|
"\tCopyright (C) 2011-2014 Leandro Nini\n"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
MOS656X::MOS656X(EventContext *context) :
|
||||||
|
Event("VIC Raster"),
|
||||||
|
event_context(*context),
|
||||||
|
sprites(regs),
|
||||||
|
badLineStateChangeEvent("Update AEC signal", *this, &MOS656X::badLineStateChange),
|
||||||
|
rasterYIRQEdgeDetectorEvent("RasterY changed", *this, &MOS656X::rasterYIRQEdgeDetector)
|
||||||
|
{
|
||||||
|
chip(MOS6569);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MOS656X::reset()
|
||||||
|
{
|
||||||
|
irqFlags = 0;
|
||||||
|
irqMask = 0;
|
||||||
|
yscroll = 0;
|
||||||
|
rasterY = maxRasters - 1;
|
||||||
|
lineCycle = 0;
|
||||||
|
areBadLinesEnabled = false;
|
||||||
|
isBadLine = false;
|
||||||
|
rasterYIRQCondition = false;
|
||||||
|
rasterClk = 0;
|
||||||
|
vblanking = false;
|
||||||
|
lpAsserted = false;
|
||||||
|
|
||||||
|
memset(regs, 0, sizeof(regs));
|
||||||
|
|
||||||
|
lp.reset();
|
||||||
|
sprites.reset();
|
||||||
|
|
||||||
|
event_context.cancel(*this);
|
||||||
|
event_context.schedule(*this, 0, EVENT_CLOCK_PHI1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MOS656X::chip(model_t model)
|
||||||
|
{
|
||||||
|
maxRasters = modelData[model].rasterLines;
|
||||||
|
cyclesPerLine = modelData[model].cyclesPerLine;
|
||||||
|
clock = modelData[model].clock;
|
||||||
|
|
||||||
|
lp.setScreenSize(maxRasters, cyclesPerLine);
|
||||||
|
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t MOS656X::read(uint_least8_t addr)
|
||||||
|
{
|
||||||
|
addr &= 0x3f;
|
||||||
|
|
||||||
|
// Sync up timers
|
||||||
|
sync();
|
||||||
|
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x11:
|
||||||
|
// Control register 1
|
||||||
|
return (regs[addr] & 0x7f) | ((rasterY & 0x100) >> 1);
|
||||||
|
case 0x12:
|
||||||
|
// Raster counter
|
||||||
|
return rasterY & 0xFF;
|
||||||
|
case 0x13:
|
||||||
|
return lp.getX();
|
||||||
|
case 0x14:
|
||||||
|
return lp.getY();
|
||||||
|
case 0x19:
|
||||||
|
// Interrupt Pending Register
|
||||||
|
return irqFlags | 0x70;
|
||||||
|
case 0x1a:
|
||||||
|
// Interrupt Mask Register
|
||||||
|
return irqMask | 0xf0;
|
||||||
|
default:
|
||||||
|
// for addresses < $20 read from register directly, when < $2f set
|
||||||
|
// bits of high nibble to 1, for >= $2f return $ff
|
||||||
|
if (addr < 0x20)
|
||||||
|
return regs[addr];
|
||||||
|
if (addr < 0x2f)
|
||||||
|
return regs[addr] | 0xf0;
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MOS656X::write(uint_least8_t addr, uint8_t data)
|
||||||
|
{
|
||||||
|
addr &= 0x3f;
|
||||||
|
|
||||||
|
regs[addr] = data;
|
||||||
|
|
||||||
|
// Sync up timers
|
||||||
|
sync();
|
||||||
|
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x11: // Control register 1
|
||||||
|
{
|
||||||
|
const unsigned int oldYscroll = yscroll;
|
||||||
|
yscroll = data & 0x7;
|
||||||
|
|
||||||
|
// This is the funniest part... handle bad line tricks.
|
||||||
|
const bool wasBadLinesEnabled = areBadLinesEnabled;
|
||||||
|
|
||||||
|
if (rasterY == FIRST_DMA_LINE && lineCycle == 0)
|
||||||
|
{
|
||||||
|
areBadLinesEnabled = readDEN();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldRasterY() == FIRST_DMA_LINE && readDEN())
|
||||||
|
{
|
||||||
|
areBadLinesEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((oldYscroll != yscroll || areBadLinesEnabled != wasBadLinesEnabled)
|
||||||
|
&& rasterY >= FIRST_DMA_LINE
|
||||||
|
&& rasterY <= LAST_DMA_LINE)
|
||||||
|
{
|
||||||
|
// Check whether bad line state has changed.
|
||||||
|
const bool wasBadLine = (wasBadLinesEnabled && (oldYscroll == (rasterY & 7)));
|
||||||
|
const bool nowBadLine = (areBadLinesEnabled && (yscroll == (rasterY & 7)));
|
||||||
|
|
||||||
|
const bool oldBadLine = isBadLine;
|
||||||
|
|
||||||
|
if (wasBadLine && !nowBadLine)
|
||||||
|
{
|
||||||
|
if (lineCycle < VICII_FETCH_CYCLE)
|
||||||
|
{
|
||||||
|
isBadLine = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!wasBadLine && nowBadLine)
|
||||||
|
{
|
||||||
|
if (lineCycle >= VICII_FETCH_CYCLE
|
||||||
|
&& lineCycle < VICII_FETCH_CYCLE + VICII_SCREEN_TEXTCOLS + 3)
|
||||||
|
{
|
||||||
|
isBadLine = true;
|
||||||
|
}
|
||||||
|
else if (lineCycle <= VICII_FETCH_CYCLE + VICII_SCREEN_TEXTCOLS + 6)
|
||||||
|
{
|
||||||
|
// Bad line has been generated after fetch interval, but
|
||||||
|
// before the raster counter is incremented.
|
||||||
|
isBadLine = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBadLine != oldBadLine)
|
||||||
|
event_context.schedule(badLineStateChangeEvent, 0, EVENT_CLOCK_PHI1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// fall-through
|
||||||
|
|
||||||
|
case 0x12: // Raster counter
|
||||||
|
// check raster Y irq condition changes at the next PHI1
|
||||||
|
event_context.schedule(rasterYIRQEdgeDetectorEvent, 0, EVENT_CLOCK_PHI1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x17:
|
||||||
|
sprites.lineCrunch(data, lineCycle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x19:
|
||||||
|
// VIC Interrupt Flag Register
|
||||||
|
irqFlags &= (~data & 0x0f) | 0x80;
|
||||||
|
handleIrqState();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x1a:
|
||||||
|
// IRQ Mask Register
|
||||||
|
irqMask = data & 0x0f;
|
||||||
|
handleIrqState();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MOS656X::handleIrqState()
|
||||||
|
{
|
||||||
|
// signal an IRQ unless we already signaled it
|
||||||
|
if ((irqFlags & irqMask & 0x0f) != 0)
|
||||||
|
{
|
||||||
|
if ((irqFlags & 0x80) == 0)
|
||||||
|
{
|
||||||
|
interrupt(true);
|
||||||
|
irqFlags |= 0x80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((irqFlags & 0x80) != 0)
|
||||||
|
{
|
||||||
|
interrupt(false);
|
||||||
|
irqFlags &= 0x7f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MOS656X::event()
|
||||||
|
{
|
||||||
|
const event_clock_t cycles = event_context.getTime(rasterClk, event_context.phase());
|
||||||
|
|
||||||
|
event_clock_t delay;
|
||||||
|
|
||||||
|
if (cycles)
|
||||||
|
{
|
||||||
|
// Update x raster
|
||||||
|
rasterClk += cycles;
|
||||||
|
lineCycle += cycles;
|
||||||
|
lineCycle %= cyclesPerLine;
|
||||||
|
|
||||||
|
delay = (this->*clock)();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
delay = 1;
|
||||||
|
|
||||||
|
event_context.schedule(*this, delay - event_context.phase(), EVENT_CLOCK_PHI1);
|
||||||
|
}
|
||||||
|
|
||||||
|
event_clock_t MOS656X::clockPAL()
|
||||||
|
{
|
||||||
|
event_clock_t delay = 1;
|
||||||
|
|
||||||
|
switch (lineCycle)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
checkVblank();
|
||||||
|
endDma<2>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
vblank();
|
||||||
|
startDma<5>();
|
||||||
|
|
||||||
|
// No sprites before next compulsory cycle
|
||||||
|
if (!sprites.isDma(0xf8))
|
||||||
|
delay = 10;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
endDma<3>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
startDma<6>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
endDma<4>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
startDma<7>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
endDma<5>();
|
||||||
|
|
||||||
|
delay = sprites.isDma(0xc0) ? 2 : 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
endDma<6>();
|
||||||
|
|
||||||
|
delay = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 9:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 10:
|
||||||
|
sprites.updateMc();
|
||||||
|
endDma<7>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 11:
|
||||||
|
startBadline();
|
||||||
|
|
||||||
|
delay = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 12:
|
||||||
|
delay = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 13:
|
||||||
|
delay = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 14:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 15:
|
||||||
|
sprites.updateMcBase();
|
||||||
|
|
||||||
|
delay = 39;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 54:
|
||||||
|
sprites.checkDma(rasterY, regs);
|
||||||
|
startDma<0>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 55:
|
||||||
|
sprites.checkDma(rasterY, regs);
|
||||||
|
sprites.checkExp();
|
||||||
|
startDma<0>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 56:
|
||||||
|
startDma<1>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 57:
|
||||||
|
sprites.checkDisplay();
|
||||||
|
|
||||||
|
// No sprites before next compulsory cycle
|
||||||
|
if (!sprites.isDma(0x1f))
|
||||||
|
delay = 6;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 58:
|
||||||
|
startDma<2>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 59:
|
||||||
|
endDma<0>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 60:
|
||||||
|
startDma<3>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 61:
|
||||||
|
endDma<1>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 62:
|
||||||
|
startDma<4>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
delay = 54 - lineCycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
event_clock_t MOS656X::clockNTSC()
|
||||||
|
{
|
||||||
|
event_clock_t delay = 1;
|
||||||
|
|
||||||
|
switch (lineCycle)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
checkVblank();
|
||||||
|
startDma<5>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
vblank();
|
||||||
|
endDma<3>();
|
||||||
|
|
||||||
|
// No sprites before next compulsory cycle
|
||||||
|
if (!sprites.isDma(0xf8))
|
||||||
|
delay = 10;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
startDma<6>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
endDma<4>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
startDma<7>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
endDma<5>();
|
||||||
|
|
||||||
|
delay = sprites.isDma(0xc0) ? 2 : 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
endDma<6>();
|
||||||
|
|
||||||
|
delay = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 9:
|
||||||
|
sprites.updateMc();
|
||||||
|
endDma<7>();
|
||||||
|
|
||||||
|
delay = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 10:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 11:
|
||||||
|
startBadline();
|
||||||
|
|
||||||
|
delay = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 12:
|
||||||
|
delay = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 13:
|
||||||
|
delay = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 14:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 15:
|
||||||
|
sprites.updateMcBase();
|
||||||
|
|
||||||
|
delay = 40;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 55:
|
||||||
|
sprites.checkDma(rasterY, regs);
|
||||||
|
sprites.checkExp();
|
||||||
|
startDma<0>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 56:
|
||||||
|
sprites.checkDma(rasterY, regs);
|
||||||
|
startDma<0>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 57:
|
||||||
|
startDma<1>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 58:
|
||||||
|
sprites.checkDisplay();
|
||||||
|
|
||||||
|
// No sprites before next compulsory cycle
|
||||||
|
if (!sprites.isDma(0x1f))
|
||||||
|
delay = 7;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 59:
|
||||||
|
startDma<2>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 60:
|
||||||
|
endDma<0>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 61:
|
||||||
|
startDma<3>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 62:
|
||||||
|
endDma<1>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 63:
|
||||||
|
startDma<4>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 64:
|
||||||
|
endDma<2>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
delay = 55 - lineCycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
event_clock_t MOS656X::clockOldNTSC()
|
||||||
|
{
|
||||||
|
event_clock_t delay = 1;
|
||||||
|
|
||||||
|
switch (lineCycle)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
checkVblank();
|
||||||
|
endDma<2>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
vblank();
|
||||||
|
startDma<5>();
|
||||||
|
|
||||||
|
// No sprites before next compulsory cycle
|
||||||
|
if (!sprites.isDma(0xf8))
|
||||||
|
delay = 10;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
endDma<3>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
startDma<6>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
endDma<4>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
startDma<7>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
endDma<5>();
|
||||||
|
|
||||||
|
delay = sprites.isDma(0xc0) ? 2 : 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
endDma<6>();
|
||||||
|
|
||||||
|
delay = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 9:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 10:
|
||||||
|
sprites.updateMc();
|
||||||
|
endDma<7>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 11:
|
||||||
|
startBadline();
|
||||||
|
|
||||||
|
delay = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 12:
|
||||||
|
delay = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 13:
|
||||||
|
delay = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 14:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 15:
|
||||||
|
sprites.updateMcBase();
|
||||||
|
|
||||||
|
delay = 40;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 55:
|
||||||
|
sprites.checkDma(rasterY, regs);
|
||||||
|
sprites.checkExp();
|
||||||
|
startDma<0>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 56:
|
||||||
|
sprites.checkDma(rasterY, regs);
|
||||||
|
startDma<0>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 57:
|
||||||
|
sprites.checkDisplay();
|
||||||
|
startDma<1>();
|
||||||
|
|
||||||
|
delay = (!sprites.isDma(0x1f)) ? 7 : 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 58:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 59:
|
||||||
|
startDma<2>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 60:
|
||||||
|
endDma<0>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 61:
|
||||||
|
startDma<3>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 62:
|
||||||
|
endDma<1>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 63:
|
||||||
|
startDma<4>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
delay = 55 - lineCycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MOS656X::triggerLightpen()
|
||||||
|
{
|
||||||
|
// Synchronise simulation
|
||||||
|
sync();
|
||||||
|
|
||||||
|
lpAsserted = true;
|
||||||
|
|
||||||
|
if (lp.trigger(lineCycle, rasterY))
|
||||||
|
{
|
||||||
|
activateIRQFlag(IRQ_LIGHTPEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MOS656X::clearLightpen()
|
||||||
|
{
|
||||||
|
lpAsserted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
libsidplayfp
|
||||||
|
============
|
||||||
|
|
||||||
|
http://sourceforge.net/projects/sidplay-residfp/
|
||||||
|
|
||||||
|
libsidplayfp is a fork of LIBSIDPLAY2, a C64 music player library which
|
||||||
|
integrates the reSID SID chip emulation into a cycle-based emulator
|
||||||
|
environment, started with primary purpose to improve emulation of the
|
||||||
|
C64 system and the SID chips.
|
||||||
|
|
||||||
|
Copyright (c) 2000-2001 Simon White
|
||||||
|
Copyright (c) 2007-2010 Antti Lankila
|
||||||
|
Copyright (c) 2010-2014 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
* Build
|
||||||
|
|
||||||
|
This package uses autotools so the usual ./configure && make is enough to build
|
||||||
|
the libraries.
|
||||||
|
In addition to the standard options the following are available:
|
||||||
|
|
||||||
|
--enable-debug[=no/yes/full]
|
||||||
|
compile with debugging messages
|
||||||
|
disabled by default
|
||||||
|
|
||||||
|
--enable-inline
|
||||||
|
enable inlinig in reSID engine, increases performances at the expense of bigger code size
|
||||||
|
enabled by default
|
||||||
|
|
||||||
|
--enable-branch-hints
|
||||||
|
enable branch hints in reSID engine so the compiler can produce more optimized code
|
||||||
|
enabled by default
|
||||||
|
|
||||||
|
--enable-mmx
|
||||||
|
enable some MMX code in reSIDfp that increases performance on old x86 processors which lack
|
||||||
|
sse2 support
|
||||||
|
disabled by default
|
||||||
|
|
||||||
|
--enable-testsuite=PATH_TO_TESTSUITE
|
||||||
|
add support for running Lorenz testsuite (in prg format). The testsuite is available
|
||||||
|
in the svn repository. Intended only for regression tests since it may break normal
|
||||||
|
code execution. The path to testsuite must include terminal path separator
|
||||||
|
disabled by default
|
||||||
|
|
||||||
|
--enable-tests
|
||||||
|
enables unit tests. Requires libUnitTest++ installed. Use "make check" to launch the testsuite
|
||||||
|
disabled by default
|
||||||
|
|
||||||
|
|
||||||
|
If doxygen is installed and detected by the configure script the documentation
|
||||||
|
can be built by invoking "make doc".
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Known bugs/limitations:
|
||||||
|
* mus data embedded in psid file is not supported
|
||||||
|
* hardsid support is untested and possibly broken
|
|
@ -0,0 +1,163 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2011-2014 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
* Copyright 2007-2010 Antti Lankila
|
||||||
|
* Copyright 2001 Simon White
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "residfp-emu.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "residfp/siddefs-fp.h"
|
||||||
|
#include "sidplayfp/siddefs.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char* ReSIDfp::getCredits()
|
||||||
|
{
|
||||||
|
if (m_credit.empty())
|
||||||
|
{
|
||||||
|
// Setup credits
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << "ReSIDfp V" << VERSION << " Engine:\n";
|
||||||
|
ss << "\t(C) 1999-2002 Simon White\n";
|
||||||
|
ss << "MOS6581 (SID) Emulation (ReSIDfp V" << residfp_version_string << "):\n";
|
||||||
|
ss << "\t(C) 1999-2002 Dag Lem\n";
|
||||||
|
ss << "\t(C) 2005-2011 Antti S. Lankila\n";
|
||||||
|
m_credit = ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_credit.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
ReSIDfp::ReSIDfp(sidbuilder *builder) :
|
||||||
|
sidemu(builder),
|
||||||
|
m_sid(*(new RESID_NAMESPACE::SID))
|
||||||
|
{
|
||||||
|
m_buffer = new short[OUTPUTBUFFERSIZE];
|
||||||
|
reset(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReSIDfp::~ReSIDfp()
|
||||||
|
{
|
||||||
|
delete &m_sid;
|
||||||
|
delete[] m_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReSIDfp::filter6581Curve(double filterCurve)
|
||||||
|
{
|
||||||
|
m_sid.setFilter6581Curve(filterCurve);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReSIDfp::filter8580Curve(double filterCurve)
|
||||||
|
{
|
||||||
|
m_sid.setFilter8580Curve(filterCurve);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Standard component options
|
||||||
|
void ReSIDfp::reset(uint8_t volume)
|
||||||
|
{
|
||||||
|
m_accessClk = 0;
|
||||||
|
m_sid.reset();
|
||||||
|
m_sid.write(0x18, volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ReSIDfp::read(uint_least8_t addr)
|
||||||
|
{
|
||||||
|
clock();
|
||||||
|
return m_sid.read(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReSIDfp::write(uint_least8_t addr, uint8_t data)
|
||||||
|
{
|
||||||
|
clock();
|
||||||
|
m_sid.write(addr, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReSIDfp::clock()
|
||||||
|
{
|
||||||
|
const event_clock_t cycles = m_context->getTime(m_accessClk, EVENT_CLOCK_PHI1);
|
||||||
|
m_accessClk += cycles;
|
||||||
|
m_bufferpos += m_sid.clock(cycles, m_buffer+m_bufferpos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReSIDfp::filter(bool enable)
|
||||||
|
{
|
||||||
|
m_sid.enableFilter(enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReSIDfp::sampling(float systemclock, float freq,
|
||||||
|
SidConfig::sampling_method_t method, bool)
|
||||||
|
{
|
||||||
|
reSIDfp::SamplingMethod sampleMethod;
|
||||||
|
switch (method)
|
||||||
|
{
|
||||||
|
case SidConfig::INTERPOLATE:
|
||||||
|
sampleMethod = reSIDfp::DECIMATE;
|
||||||
|
break;
|
||||||
|
case SidConfig::RESAMPLE_INTERPOLATE:
|
||||||
|
sampleMethod = reSIDfp::RESAMPLE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
m_status = false;
|
||||||
|
m_error = ERR_INVALID_SAMPLING;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Round half frequency to the nearest multiple of 5000
|
||||||
|
const int halfFreq = 5000*((static_cast<int>(freq)+5000)/10000);
|
||||||
|
m_sid.setSamplingParameters(systemclock, sampleMethod, freq, std::min(halfFreq, 20000));
|
||||||
|
}
|
||||||
|
catch (RESID_NAMESPACE::SIDError const &)
|
||||||
|
{
|
||||||
|
m_status = false;
|
||||||
|
m_error = ERR_UNSUPPORTED_FREQ;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_status = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the emulated SID model
|
||||||
|
void ReSIDfp::model(SidConfig::sid_model_t model)
|
||||||
|
{
|
||||||
|
reSIDfp::ChipModel chipModel;
|
||||||
|
switch (model)
|
||||||
|
{
|
||||||
|
case SidConfig::MOS6581:
|
||||||
|
chipModel = reSIDfp::MOS6581;
|
||||||
|
break;
|
||||||
|
case SidConfig::MOS8580:
|
||||||
|
chipModel = reSIDfp::MOS8580;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
m_status = false;
|
||||||
|
m_error = ERR_INVALID_CHIP;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_sid.setChipModel(chipModel);
|
||||||
|
m_status = true;
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2014 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MD5_INTERNAL_H
|
||||||
|
#define MD5_INTERNAL_H
|
||||||
|
|
||||||
|
#include "iMd5.h"
|
||||||
|
|
||||||
|
#include "MD5/MD5.h"
|
||||||
|
|
||||||
|
#include "sidcxx11.h"
|
||||||
|
|
||||||
|
namespace libsidplayfp
|
||||||
|
{
|
||||||
|
|
||||||
|
class md5Internal : public iMd5
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
MD5 hd;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void append(const void* data, int nbytes) override { hd.append(data, nbytes); }
|
||||||
|
|
||||||
|
void finish() override { hd.finish(); }
|
||||||
|
|
||||||
|
const unsigned char* getDigest() override { return hd.getDigest(); }
|
||||||
|
|
||||||
|
void reset() override { hd.reset(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,218 @@
|
||||||
|
/*
|
||||||
|
* This file is part of libsidplayfp, a SID player engine.
|
||||||
|
*
|
||||||
|
* Copyright 2013 Leandro Nini <drfiemost@users.sourceforge.net>
|
||||||
|
* Copyright 2007-2010 Antti Lankila
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PARAMETERS_H
|
||||||
|
#define PARAMETERS_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
class Parameters
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
BIAS,
|
||||||
|
PULSESTRENGTH,
|
||||||
|
TOPBIT,
|
||||||
|
DISTANCE,
|
||||||
|
STMIX
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
float bias, pulsestrength, topbit, distance, stmix;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Parameters() { reset(); }
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
bias = 0.f;
|
||||||
|
pulsestrength = 0.f;
|
||||||
|
topbit = 0.f;
|
||||||
|
distance = 0.f;
|
||||||
|
stmix = 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float GetValue(int i)
|
||||||
|
{
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case BIAS: return bias;
|
||||||
|
case PULSESTRENGTH: return pulsestrength;
|
||||||
|
case TOPBIT: return topbit;
|
||||||
|
case DISTANCE: return distance;
|
||||||
|
case STMIX: return stmix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetValue(int i, float v)
|
||||||
|
{
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case BIAS: bias = v; break;
|
||||||
|
case PULSESTRENGTH: pulsestrength = v; break;
|
||||||
|
case TOPBIT: topbit = v; break;
|
||||||
|
case DISTANCE: distance = v; break;
|
||||||
|
case STMIX: stmix = v; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string toString()
|
||||||
|
{
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << "bias = " << bias << std::endl;
|
||||||
|
ss << "pulsestrength = " << pulsestrength << std::endl;
|
||||||
|
ss << "topbit = " << topbit << std::endl;
|
||||||
|
ss << "distance = " << distance << std::endl;
|
||||||
|
ss << "stmix = " << stmix << std::endl;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SimulateMix(float bitarray[12], float wa[], bool HasPulse)
|
||||||
|
{
|
||||||
|
float tmp[12];
|
||||||
|
|
||||||
|
for (int sb = 0; sb < 12; sb ++)
|
||||||
|
{
|
||||||
|
float n = 0.f;
|
||||||
|
float avg = 0.f;
|
||||||
|
for (int cb = 0; cb < 12; cb ++)
|
||||||
|
{
|
||||||
|
const float weight = wa[sb - cb + 12];
|
||||||
|
avg += bitarray[cb] * weight;
|
||||||
|
n += weight;
|
||||||
|
}
|
||||||
|
if (HasPulse)
|
||||||
|
{
|
||||||
|
const float weight = wa[sb - 12 + 12];
|
||||||
|
avg += pulsestrength * weight;
|
||||||
|
n += weight;
|
||||||
|
}
|
||||||
|
tmp[sb] = (bitarray[sb] + avg / n) * 0.5f;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 12; i ++)
|
||||||
|
bitarray[i] = tmp[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetScore8(float bitarray[12])
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
for (int cb = 0; cb < 8; cb ++)
|
||||||
|
{
|
||||||
|
if (bitarray[4+cb] > bias)
|
||||||
|
result |= 1 << cb;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ScoreResult(int a, int b)
|
||||||
|
{
|
||||||
|
// audible error
|
||||||
|
int v = a ^ b;
|
||||||
|
return v;
|
||||||
|
/* int c = 0;
|
||||||
|
while (v != 0)
|
||||||
|
{
|
||||||
|
v &= v - 1;
|
||||||
|
c ++;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
int Score(int wave, const std::vector<int> &reference, bool print, int bestscore)
|
||||||
|
{
|
||||||
|
int score = 0;
|
||||||
|
float wa[12 + 12 + 1];
|
||||||
|
for (int i = 0; i <= 12; i ++)
|
||||||
|
{
|
||||||
|
wa[12-i] = wa[12+i] = 1.0f / (1.0f + i * i * distance);
|
||||||
|
}
|
||||||
|
for (int j = 4095; j >= 0; j --)
|
||||||
|
{
|
||||||
|
/* S */
|
||||||
|
float bitarray[12];
|
||||||
|
for (int i = 0; i < 12; i ++)
|
||||||
|
bitarray[i] = (j & (1 << i)) != 0 ? 1.f : 0.f;
|
||||||
|
|
||||||
|
/* T */
|
||||||
|
if ((wave & 3) == 1)
|
||||||
|
{
|
||||||
|
const bool top = (j & 2048) != 0;
|
||||||
|
for (int i = 11; i > 0; i --)
|
||||||
|
{
|
||||||
|
bitarray[i] = top ? 1.f - bitarray[i-1] : bitarray[i-1];
|
||||||
|
}
|
||||||
|
bitarray[0] = 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ST */
|
||||||
|
if ((wave & 3) == 3)
|
||||||
|
{
|
||||||
|
bitarray[0] *= stmix;
|
||||||
|
for (int i = 1; i < 12; i ++)
|
||||||
|
{
|
||||||
|
bitarray[i] = bitarray[i-1] * (1.f - stmix) + bitarray[i] * stmix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bitarray[11] *= topbit;
|
||||||
|
|
||||||
|
SimulateMix(bitarray, wa, wave > 4);
|
||||||
|
|
||||||
|
const int simval = GetScore8(bitarray);
|
||||||
|
const int refval = reference[j];
|
||||||
|
score += ScoreResult(simval, refval);
|
||||||
|
|
||||||
|
if (print)
|
||||||
|
{
|
||||||
|
float analogval = 0.f;
|
||||||
|
for (int i = 0; i < 12; i ++)
|
||||||
|
{
|
||||||
|
float val = (bitarray[i] - bias) * 512 + 0.5f;
|
||||||
|
if (val < 0.f)
|
||||||
|
val = 0.f;
|
||||||
|
else if (val > 1.f)
|
||||||
|
val = 1.f;
|
||||||
|
analogval += val * (1 << i);
|
||||||
|
}
|
||||||
|
analogval /= 16.f;
|
||||||
|
std::cout << j << " "
|
||||||
|
<< refval << " "
|
||||||
|
<< simval << " "
|
||||||
|
<< analogval << " "
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (score > bestscore)
|
||||||
|
{
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Binary file not shown.
|
@ -0,0 +1,69 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import math, random
|
||||||
|
from scipy.fftpack import fft
|
||||||
|
from scipy import array
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def pow2db(x):
|
||||||
|
if x < 1e-9:
|
||||||
|
return -99
|
||||||
|
return math.log(x) / math.log(10) * 10
|
||||||
|
|
||||||
|
Vi = 0
|
||||||
|
Vbp = 0
|
||||||
|
Vlp = 0
|
||||||
|
Vhp = 0
|
||||||
|
|
||||||
|
w0 = 0.0628318
|
||||||
|
distortion_rate = 1
|
||||||
|
res = 15
|
||||||
|
|
||||||
|
def do_filter_combined():
|
||||||
|
Q = 0.5 + res / 20.
|
||||||
|
global Vi, Vbp, Vlp, Vhp
|
||||||
|
|
||||||
|
Vlp -= w0 * Vbp
|
||||||
|
Vbp -= w0 * Vhp
|
||||||
|
Vhp_construction = Vbp / Q - Vlp - Vi
|
||||||
|
Vhp = Vhp_construction * 0.6
|
||||||
|
|
||||||
|
FFT_SIZE = 8192
|
||||||
|
def main_fft(variable, _res):
|
||||||
|
global Vi, res
|
||||||
|
res = _res;
|
||||||
|
|
||||||
|
if (variable == 'Vlp'):
|
||||||
|
def func(): return Vlp
|
||||||
|
elif (variable == 'Vbp'):
|
||||||
|
def func(): return Vbp
|
||||||
|
elif (variable == 'Vhp'):
|
||||||
|
def func(): return Vhp
|
||||||
|
elif (variable == 'sum'):
|
||||||
|
def func(): return Vlp + Vbp + Vhp
|
||||||
|
elif (variable == 'sum_lo'):
|
||||||
|
def func(): return Vlp + Vbp
|
||||||
|
elif (variable == 'sum_hi'):
|
||||||
|
def func(): return Vbp + Vhp
|
||||||
|
elif (variable == 'sum_notch'):
|
||||||
|
def func(): return Vlp + Vhp
|
||||||
|
else:
|
||||||
|
raise RuntimeError, "Unknown variable: %s" % variable
|
||||||
|
|
||||||
|
tmp1 = []
|
||||||
|
Vi = 1.0;
|
||||||
|
for x in range(FFT_SIZE):
|
||||||
|
do_filter_combined()
|
||||||
|
tmp1.append(func())
|
||||||
|
Vi = 0
|
||||||
|
|
||||||
|
accum1 = abs(fft(tmp1)) ** 2
|
||||||
|
|
||||||
|
for i in range(len(accum1)/2):
|
||||||
|
print "%f %f" % (float(i) / FFT_SIZE * 1000000, pow2db(accum1[i]))
|
||||||
|
|
||||||
|
def main():
|
||||||
|
return main_fft(sys.argv[1], float(sys.argv[2]))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue