Implemented basic residfp support
parent
540069c019
commit
08dc22009d
|
@ -142,6 +142,7 @@
|
|||
835CBC8118DA7A520087A03E /* modplay.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 835CBC7618DA79F80087A03E /* modplay.bundle */; };
|
||||
8360EF6D17F92E56005208A4 /* HighlyComplete.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8360EF0517F92B24005208A4 /* HighlyComplete.bundle */; };
|
||||
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 */; };
|
||||
836FB5A718206F2500B3AD2D /* Hively.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 836FB5471820538800B3AD2D /* Hively.bundle */; };
|
||||
8375B36517FFEF130092A79F /* Opus.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8375B05717FFEA410092A79F /* Opus.bundle */; };
|
||||
|
@ -423,6 +424,13 @@
|
|||
remoteGlobalIDString = 99B989F40CC7E10400C256E9;
|
||||
remoteInfo = "APL Plugin";
|
||||
};
|
||||
8314D6401A354DFF00EEE8E6 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 8314D63B1A354DFE00EEE8E6 /* sidplay.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 8314D6311A354DFE00EEE8E6;
|
||||
remoteInfo = sidplay;
|
||||
};
|
||||
8359FF3017FEF35D0060F3ED /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 8359FF2C17FEF35C0060F3ED /* ArchiveSource.xcodeproj */;
|
||||
|
@ -444,6 +452,13 @@
|
|||
remoteGlobalIDString = 8360EEE417F92AC8005208A4;
|
||||
remoteInfo = HighlyComplete;
|
||||
};
|
||||
836F5BED1A3579F5002730CC /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 8314D63B1A354DFE00EEE8E6 /* sidplay.xcodeproj */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 8314D6301A354DFE00EEE8E6;
|
||||
remoteInfo = sidplay;
|
||||
};
|
||||
836F6B2D18BDB80E0095E648 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 836F6B2518BDB80D0095E648 /* vgmstream.xcodeproj */;
|
||||
|
@ -651,6 +666,7 @@
|
|||
dstPath = "";
|
||||
dstSubfolderSpec = 13;
|
||||
files = (
|
||||
836F5BF91A357A01002730CC /* sidplay.bundle in CopyFiles */,
|
||||
839BD010196521E600947767 /* BASSMODS.bundle in CopyFiles */,
|
||||
835CBC8118DA7A520087A03E /* modplay.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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
|
@ -1261,6 +1278,7 @@
|
|||
836FB5421820538700B3AD2D /* Hively.xcodeproj */,
|
||||
836F6B2518BDB80D0095E648 /* vgmstream.xcodeproj */,
|
||||
839BCFE71965133E00947767 /* BASSMODS.xcodeproj */,
|
||||
8314D63B1A354DFE00EEE8E6 /* sidplay.xcodeproj */,
|
||||
);
|
||||
name = PlugIns;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1575,6 +1593,14 @@
|
|||
name = Categories;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8314D63C1A354DFE00EEE8E6 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8314D6411A354DFF00EEE8E6 /* sidplay.bundle */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8359FF2D17FEF35C0060F3ED /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -1679,9 +1705,9 @@
|
|||
children = (
|
||||
83E6B759181612FD00D4576D /* Sparkle.framework */,
|
||||
83E6B75B181612FD00D4576D /* Sparkle Test App.app */,
|
||||
83E6B75D181612FD00D4576D /* Sparkle Unit Tests.octest */,
|
||||
83E6B75D181612FD00D4576D /* Sparkle Unit Tests.xctest */,
|
||||
83E6B75F181612FD00D4576D /* BinaryDelta */,
|
||||
83E6B761181612FD00D4576D /* finish_installation.app */,
|
||||
83E6B761181612FD00D4576D /* Autoupdate.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1818,6 +1844,7 @@
|
|||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
836F5BEE1A3579F5002730CC /* PBXTargetDependency */,
|
||||
839BD012196521FD00947767 /* PBXTargetDependency */,
|
||||
836FB5A618206F1500B3AD2D /* PBXTargetDependency */,
|
||||
83A0F4E21816DBE800119DB4 /* PBXTargetDependency */,
|
||||
|
@ -1973,6 +2000,10 @@
|
|||
ProductGroup = 17C808A80C3BD1BA005707C4 /* Products */;
|
||||
ProjectRef = 17C808A70C3BD1BA005707C4 /* Shorten.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 8314D63C1A354DFE00EEE8E6 /* Products */;
|
||||
ProjectRef = 8314D63B1A354DFE00EEE8E6 /* sidplay.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 83E6B751181612FD00D4576D /* Products */;
|
||||
ProjectRef = 83E6B750181612FD00D4576D /* Sparkle.xcodeproj */;
|
||||
|
@ -2107,6 +2138,13 @@
|
|||
remoteRef = 566D321A0D538550004466A5 /* PBXContainerItemProxy */;
|
||||
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 */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.cfbundle;
|
||||
|
@ -2191,10 +2229,10 @@
|
|||
remoteRef = 83E6B75A181612FD00D4576D /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
83E6B75D181612FD00D4576D /* Sparkle Unit Tests.octest */ = {
|
||||
83E6B75D181612FD00D4576D /* Sparkle Unit Tests.xctest */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.cfbundle;
|
||||
path = "Sparkle Unit Tests.octest";
|
||||
path = "Sparkle Unit Tests.xctest";
|
||||
remoteRef = 83E6B75C181612FD00D4576D /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
|
@ -2205,10 +2243,10 @@
|
|||
remoteRef = 83E6B75E181612FD00D4576D /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
83E6B761181612FD00D4576D /* finish_installation.app */ = {
|
||||
83E6B761181612FD00D4576D /* Autoupdate.app */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.application;
|
||||
path = finish_installation.app;
|
||||
path = Autoupdate.app;
|
||||
remoteRef = 83E6B760181612FD00D4576D /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
|
@ -2510,6 +2548,11 @@
|
|||
name = General;
|
||||
targetProxy = 17F5623A0C3BD9280019975C /* PBXContainerItemProxy */;
|
||||
};
|
||||
836F5BEE1A3579F5002730CC /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = sidplay;
|
||||
targetProxy = 836F5BED1A3579F5002730CC /* PBXContainerItemProxy */;
|
||||
};
|
||||
836FB5A618206F1500B3AD2D /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = Hively;
|
||||
|
|
|
@ -8,14 +8,23 @@
|
|||
<string>811E8515-6C50-44FF-ACDB-088BB9917E26</string>
|
||||
<key>IDESourceControlProjectOriginsDictionary</key>
|
||||
<dict>
|
||||
<key>75748be7-0387-4326-94c7-f41ce0883d2c++505</key>
|
||||
<string>svn://svn.code.sf.net/p/sidplay-residfp/code/trunk</string>
|
||||
<key>EF1CF5E1F342919DE309B5C9DAEDDCF1D12D0402</key>
|
||||
<string>https://github.com/andymatuschak/Sparkle.git</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
|
||||
<dict>
|
||||
<key>75748be7-0387-4326-94c7-f41ce0883d2c++505</key>
|
||||
<string>libsidplay/sidplay-residfp-code/</string>
|
||||
<key>EF1CF5E1F342919DE309B5C9DAEDDCF1D12D0402</key>
|
||||
<string>Sparkle/</string>
|
||||
</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>
|
||||
<string>https://github.com/andymatuschak/Sparkle.git</string>
|
||||
<key>IDESourceControlProjectVersion</key>
|
||||
|
@ -24,6 +33,14 @@
|
|||
<string>EF1CF5E1F342919DE309B5C9DAEDDCF1D12D0402</string>
|
||||
<key>IDESourceControlProjectWCConfigurations</key>
|
||||
<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>
|
||||
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
|
||||
<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