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

174 lines
4.6 KiB
Text

/*
* 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 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 EVENT_H
#define EVENT_H
#include <stdint.h>
#include "sidplayfp/siddefs.h"
typedef int_fast64_t event_clock_t;
/**
* C64 system runs actions at system clock high and low
* states. The PHI1 corresponds to the auxiliary chip activity
* and PHI2 to CPU activity. For any clock, PHI1s are before
* PHI2s.
*/
typedef enum {EVENT_CLOCK_PHI1 = 0, EVENT_CLOCK_PHI2 = 1} event_phase_t;
/**
* Event scheduler (based on alarm from Vice). Created in 2001 by Simon A.
* White.
*
* Optimized EventScheduler and corresponding Event class by Antti S. Lankila
* in 2009.
*
* @author Antti Lankila
*/
class SID_EXTERN Event
{
friend class EventScheduler;
private:
/**
* The next event in sequence.
*/
Event *next;
/**
* The clock this event fires.
*/
event_clock_t triggerTime;
/**
* Describe event for humans.
*/
const char * const m_name;
public:
/**
* Events are used for delayed execution. Name is
* not used by code, but is useful for debugging.
*
* @param name Descriptive string of the event.
*/
Event(const char * const name) :
m_name(name) {}
/**
* Event code to be executed. Events are allowed to safely
* reschedule themselves with the EventScheduler during
* invocations.
*/
virtual void event() = 0;
protected:
~Event() {}
};
/**
* Fast EventScheduler, which maintains a linked list of Events.
* This scheduler takes neglible time even when it is used to
* schedule events for nearly every clock.
*
* Events occur on an internal clock which is 2x the visible clock.
* The visible clock is divided to two phases called phi1 and phi2.
*
* The phi1 clocks are used by VIC and CIA chips, phi2 clocks by CPU.
*
* Scheduling an event for a phi1 clock when system is in phi2 causes the
* event to be moved to the next phi1 cycle. Correspondingly, requesting
* a phi1 time when system is in phi2 returns the value of the next phi1.
*
* @author Antti S. Lankila
*/
class EventContext
{
public:
/**
* Cancel the specified event.
*
* @param event the event to cancel
*/
virtual void cancel(Event &event) = 0;
/**
* Add event to pending queue.
*
* At PHI2, specify cycles=0 and Phase=PHI1 to fire on the very next PHI1.
*
* @param event the event to add
* @param cycles how many cycles from now to fire
* @param phase the phase when to fire the event
*/
virtual void schedule(Event &event, event_clock_t cycles,
event_phase_t phase) = 0;
/**
* Add event to pending queue in the same phase as current event.
*
* @param event the event to add
* @param cycles how many cycles from now to fire
*/
virtual void schedule(Event &event, event_clock_t cycles) = 0;
/**
* Is the event pending in this scheduler?
*
* @param event the event
* @return true when pending
*/
virtual bool isPending(Event &event) const = 0;
/**
* Get time with respect to a specific clock phase.
*
* @param phase the phase
* @return the time according to specified phase.
*/
virtual event_clock_t getTime(event_phase_t phase) const = 0;
/**
* Get clocks since specified clock in given phase.
*
* @param clock the time to compare to
* @param phase the phase to comapre to
* @return the time between specified clock and now
*/
virtual event_clock_t getTime(event_clock_t clock, event_phase_t phase) const = 0;
/**
* Return current clock phase.
*
* @return The current phase
*/
virtual event_phase_t phase() const = 0;
protected:
~EventContext() {}
};
#endif // EVENT_H