1 /*************************************************************************** 2 event.h - Event scheduler (based on alarm 3 from Vice) 4 ------------------- 5 begin : Wed May 9 2001 6 copyright : (C) 2001 by Simon White 7 email : s_a_white@email.com 8 ***************************************************************************/ 9 10 /*************************************************************************** 11 * * 12 * This program is free software; you can redistribute it and/or modify * 13 * it under the terms of the GNU General Public License as published by * 14 * the Free Software Foundation; either version 2 of the License, or * 15 * (at your option) any later version. * 16 * * 17 ***************************************************************************/ 18 19 #ifndef _event_h_ 20 #define _event_h_ 21 22 #include <stdio.h> 23 #include "sidtypes.h" 24 25 typedef uint_fast32_t event_clock_t; 26 typedef enum {EVENT_CLOCK_PHI1 = 0, EVENT_CLOCK_PHI2 = 1} event_phase_t; 27 #define EVENT_CONTEXT_MAX_PENDING_EVENTS 0x100 28 29 class SID_EXTERN Event 30 { 31 friend class EventScheduler; 32 33 public: 34 const char * const m_name; 35 event_clock_t m_clk; 36 37 /* This variable is set by the event context 38 when it is scheduled */ 39 bool m_pending; 40 41 /* Link to the next and previous events in the 42 list. */ 43 Event *m_next, *m_prev; 44 45 public: Event(const char * const name)46 Event(const char * const name) 47 : m_name(name), 48 m_pending(false) {} 49 50 virtual void event (void) = 0; pending()51 bool pending () { return m_pending; } 52 }; 53 54 // Public Event Context 55 class EventContext 56 { 57 public: 58 virtual void cancel (Event *event) = 0; 59 virtual void schedule (Event *event, event_clock_t cycles, 60 event_phase_t phase) = 0; 61 virtual event_clock_t getTime (event_phase_t phase) const = 0; 62 virtual event_clock_t getTime (event_clock_t clock, event_phase_t phase) const = 0; 63 virtual event_phase_t phase () const = 0; 64 }; 65 66 // Private Event Context Object (The scheduler) 67 class EventScheduler: public EventContext, public Event 68 { 69 private: 70 event_clock_t m_absClk; 71 uint m_events; 72 73 class SID_EXTERN EventTimeWarp: public Event 74 { 75 private: 76 EventScheduler &m_scheduler; 77 event(void)78 void event (void) 79 { 80 m_scheduler.event (); 81 } 82 83 public: EventTimeWarp(EventScheduler * context)84 EventTimeWarp (EventScheduler *context) 85 :Event("Time Warp"), 86 m_scheduler(*context) 87 {;} 88 } m_timeWarp; 89 friend class EventTimeWarp; 90 91 private: 92 void event (void); dispatch(Event & e)93 void dispatch (Event &e) 94 { 95 cancelPending (e); 96 //printf ("Event \"%s\"\n", e.m_name); 97 e.event (); 98 } 99 cancelPending(Event & event)100 void cancelPending (Event &event) 101 { 102 event.m_pending = false; 103 event.m_prev->m_next = event.m_next; 104 event.m_next->m_prev = event.m_prev; 105 m_events--; 106 } 107 108 public: 109 EventScheduler (const char * const name); 110 void cancel (Event *event); 111 void reset (void); 112 void schedule (Event *event, event_clock_t cycles, 113 event_phase_t phase); 114 clock(void)115 void clock (void) 116 { 117 // m_clk++; 118 // while (m_events && (m_clk >= m_next->m_clk)) 119 // dispatch (*m_next); 120 m_clk = m_next->m_clk; 121 dispatch (*m_next); 122 } 123 124 // Get time with respect to a specific clock phase getTime(event_phase_t phase)125 event_clock_t getTime (event_phase_t phase) const 126 { return (m_absClk + m_clk + (phase ^ 1)) >> 1; } getTime(event_clock_t clock,event_phase_t phase)127 event_clock_t getTime (event_clock_t clock, event_phase_t phase) const 128 { return ((getTime (phase) - clock) << 1) >> 1; } // 31 bit res. phase()129 event_phase_t phase () const { return (event_phase_t) ((m_absClk + m_clk) & 1); } 130 }; 131 132 #endif // _event_h_ 133