OSDN Git Service

* public snapshot of sid simulator
[pf3gnuchains/pf3gnuchains3x.git] / sid / include / sidschedutil.h
1 // sidschedutil.h - Useful mix-in classes for interfacing to the
2 // generic scheduler components.  -*- C++ -*-
3
4 // Copyright (C) 1999, 2000 Red Hat.
5 // This file is part of SID and is licensed under the GPL.
6 // See the file COPYING.SID for conditions for redistribution.
7
8 #ifndef H_SIDSCHEDUTIL_H
9 #define H_SIDSCHEDUTIL_H
10
11 #include <sidconfig.h>
12
13 #include <sidcomp.h>
14 #include <sidpinutil.h>
15
16 #include <string>
17 #include <vector>
18 #include <map>
19
20 namespace sidutil
21 {
22   // The template <Master> class should be a kind of
23   // fixed_pin_map_component so we can register the various
24   // communication pins.
25   
26   template <class Master>
27   class scheduler_event_subscription
28   {
29   public:
30     scheduler_event_subscription(const std::string& name,
31                                  Master* c,
32                                  void (Master::*f)()):
33       master (c),
34       pmf (f),
35       event_pin (this, & scheduler_event_subscription<Master>::event_handler)
36       {
37         // It's not important to remove these at destruction time.
38         master->add_pin (name + "-control", & this->control_pin);
39         master->add_pin (name + "-event", & this->event_pin);
40       }
41     
42     void cancel() { this->control_pin.drive (0); }
43     
44     void schedule(bool regular_p, sid::host_int_4 time)
45       {
46         assert ((time & 0x80000000) == 0);
47         assert ((time & 0x7FFFFFFF) != 0);
48         sid::host_int_4 value = regular_p ? (0x80000000 | time) : (time);
49         this->control_pin.drive(value);
50       }
51     
52     void schedule_irregular(sid::host_int_4 time)
53       {
54         this->schedule(false, time);
55       }
56     
57     void schedule_regular(sid::host_int_4 time)
58       {
59         this->schedule(true, time);
60       }
61     
62   private:
63     Master* master;
64     void (Master::*pmf)();
65     sidutil::output_pin control_pin;
66     sidutil::callback_pin<sidutil::scheduler_event_subscription<Master> > event_pin;
67     void event_handler (sid::host_int_4)
68       {
69         (master->*pmf) ();
70       }
71   };
72   
73   
74   // The template <Master> class should be a kind of
75   // fixed_pin_map_component so we can register the various
76   // communication pins.
77
78   template <class Master>
79   class scheduler_time_query
80   {
81   public:
82     // The constructor must specify the component to whom we belong.
83     scheduler_time_query(Master* m)
84       :master(m)
85       {
86         master->add_pin ("time-query", & this->query_pin);
87         master->add_pin ("time-high", & this->result_high_pin);
88         master->add_pin ("time-low", & this->result_low_pin);
89       }
90     
91     // XXX: This could be a host_int_8 just as easily, but Cygwin g++
92     // seems to have problems returning that type in some contexts.
93     
94     sid::host_int_8 now()
95       {
96         this->query_pin.drive (0);
97         // We should receive a callback on both result_*_pins.
98         sid::host_int_4 high = this->result_high_pin.sense();
99         sid::host_int_4 low = this->result_low_pin.sense();
100         sid::host_int_8 value = 
101           (((sid::host_int_8) high) << 32) | (sid::host_int_8) low;
102         return value;
103       }
104
105   private:
106     Master* master;
107     sidutil::output_pin query_pin;
108     sidutil::input_pin result_high_pin;
109     sidutil::input_pin result_low_pin;
110   };
111
112 } // namespace sidutil
113
114 #endif // SIDSCHEDUTIL_H