Cog/Frameworks/libsidplay/sidplay-residfp-code/.svn/pristine/ed/edf6d8142bca3445caa681fe4e747ac864d33c9e.svn-base
2014-12-07 22:26:31 -08:00

189 lines
4.5 KiB
Text

/*
* 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-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.
*/
#include "hardsid-emu.h"
#include <cstdio>
#include <sstream>
#include <string>
#include "hardsid.h"
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
/***************************************************************************
Hardsid support interface.
Created from Jarnos original
Sidplay2 patch
***************************************************************************/
extern HsidDLL2 hsid2;
const unsigned int HardSID::voices = HARDSID_VOICES;
unsigned int HardSID::sid = 0;
const char* HardSID::getCredits()
{
if (m_credit.empty())
{
// Setup credits
std::ostringstream ss;
ss << "HardSID V" << VERSION << " Engine:\n";
ss << "\t(C) 1999-2002 Simon White\n";
m_credit = ss.str();
}
return m_credit.c_str();
}
HardSID::HardSID(sidbuilder *builder) :
sidemu(builder),
Event("HardSID Delay"),
m_instance(sid++)
{
if (m_instance >= hsid2.Devices ())
{
m_error = "HARDSID WARNING: System dosen't have enough SID chips.";
return;
}
m_status = true;
reset();
}
HardSID::~HardSID()
{
sid--;
}
void HardSID::clock()
{
return;
}
uint8_t HardSID::read(uint_least8_t addr)
{
event_clock_t cycles = m_context->getTime(m_accessClk, EVENT_CLOCK_PHI1);
m_accessClk += cycles;
while (cycles > 0xFFFF)
{
hsid2.Delay((BYTE) m_instance, 0xFFFF);
cycles -= 0xFFFF;
}
return hsid2.Read((BYTE) m_instance, (WORD) cycles,
(BYTE) addr);
}
void HardSID::write(uint_least8_t addr, uint8_t data)
{
event_clock_t cycles = m_context->getTime(m_accessClk, EVENT_CLOCK_PHI1);
m_accessClk += cycles;
while (cycles > 0xFFFF)
{
hsid2.Delay((BYTE) m_instance, 0xFFFF);
cycles -= 0xFFFF;
}
hsid2.Write((BYTE) m_instance, (WORD) cycles,
(BYTE) addr, (BYTE) data);
}
void HardSID::reset(uint8_t volume)
{
m_accessClk = 0;
// Clear hardsid buffers
hsid2.Flush ((BYTE) m_instance);
if (hsid2.Version >= HSID_VERSION_204)
hsid2.Reset2((BYTE) m_instance, volume);
else
hsid2.Reset((BYTE) m_instance);
hsid2.Sync((BYTE) m_instance);
if (m_context != 0)
m_context->schedule(*this, HARDSID_DELAY_CYCLES, EVENT_CLOCK_PHI1);
}
void HardSID::voice(unsigned int num, bool mute)
{
if (hsid2.Version >= HSID_VERSION_207)
hsid2.Mute2((BYTE) m_instance, (BYTE) num, (BOOL) mute, FALSE);
else
hsid2.Mute((BYTE) m_instance, (BYTE) num, (BOOL) mute);
}
// Set execution environment and lock sid to it
bool HardSID::lock(EventContext *env)
{
if (hsid2.Version >= HSID_VERSION_204)
{
if (hsid2.Lock(m_instance) == FALSE)
return false;
}
sidemu::lock(env);
m_context->schedule(*this, HARDSID_DELAY_CYCLES, EVENT_CLOCK_PHI1);
return true;
}
// Unlock sid
void HardSID::unlock()
{
if (hsid2.Version >= HSID_VERSION_204)
hsid2.Unlock(m_instance);
m_context->cancel(*this);
sidemu::unlock();
}
void HardSID::event()
{
event_clock_t cycles = m_context->getTime(m_accessClk, EVENT_CLOCK_PHI1);
if (cycles < HARDSID_DELAY_CYCLES)
{
m_context->schedule(*this, HARDSID_DELAY_CYCLES - cycles,
EVENT_CLOCK_PHI1);
}
else
{
m_accessClk += cycles;
hsid2.Delay((BYTE) m_instance, (WORD) cycles);
m_context->schedule(*this, HARDSID_DELAY_CYCLES,
EVENT_CLOCK_PHI1);
}
}
// Disable/Enable SID filter
void HardSID::filter(bool enable)
{
hsid2.Filter((BYTE) m_instance, (BOOL) enable);
}
void HardSID::flush()
{
hsid2.Flush((BYTE) m_instance);
}