1 /* 2 * KCemu -- The emulator for the KC85 homecomputer series and much more. 3 * Copyright (C) 1997-2010 Torsten Paul 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 #ifndef __kc_ctc_h 21 #define __kc_ctc_h 22 23 #include <list> 24 25 #include "kc/system.h" 26 27 #include "kc/ic.h" 28 #include "kc/cb.h" 29 #include "kc/ports.h" 30 31 class CTCCallbackInterface 32 { 33 public: CTCCallbackInterface(void)34 CTCCallbackInterface(void) {} ~CTCCallbackInterface(void)35 virtual ~CTCCallbackInterface(void) {} 36 37 virtual void ctc_callback_ZC(int channel) = 0; 38 virtual void ctc_callback_TC(int channel, long tc) = 0; 39 virtual void ctc_callback_start(int channel) = 0; 40 virtual void ctc_callback_stop(int channel) = 0; 41 }; 42 43 class CTC : public InterfaceCircuit, public PortInterface, public Callback 44 { 45 protected: 46 typedef std::list<CTCCallbackInterface *>cb_list_t; 47 typedef cb_list_t::iterator iterator; 48 49 enum { 50 IRQ = 0x80, 51 IRQ_DISABLED = 0x00, 52 IRQ_ENABLED = 0x80, 53 54 MODE = 0x40, 55 MODE_TIMER = 0x00, 56 MODE_COUNTER = 0x40, 57 58 PRESCALER = 0x20, 59 PRESCALER_16 = 0x00, 60 PRESCALER_256 = 0x20, 61 62 EDGE = 0x10, 63 EDGE_FALLING = 0x00, 64 EDGE_RISING = 0x10, 65 66 TRIGGER = 0x08, 67 TRIGGER_AUTO = 0x00, 68 TRIGGER_CLOCK = 0x08, 69 70 CONSTANT = 0x04, 71 CONSTANT_NONE = 0x00, 72 CONSTANT_LOAD = 0x04, 73 74 RESET = 0x02, 75 RESET_NONE = 0x00, 76 RESET_ACTIVE = 0x02, 77 78 CONTROL = 0x01, 79 CONTROL_VECTOR = 0x00, 80 CONTROL_WORD = 0x01, 81 }; 82 83 byte_t _irq_vector; 84 byte_t _control[4]; 85 word_t _value[4]; 86 word_t _timer_value[4]; 87 byte_t _restart[4]; 88 long long _counter[4]; 89 90 byte_t _irq_pending[4]; 91 byte_t _irq_active[4]; 92 long _irq_valid[4]; 93 94 cb_list_t *_cb_list[4]; 95 96 private: 97 void handle_counter_mode(int channel); 98 99 protected: 100 virtual long long get_counter() = 0; 101 virtual void trigger_irq(int channel) = 0; 102 virtual void add_callback(unsigned long long offset, Callback *cb, void *data) = 0; 103 104 virtual void try_trigger_irq(int channel); 105 106 public: 107 CTC(const char *name); 108 virtual ~CTC(void); 109 110 virtual bool irq_0(void) = 0; 111 virtual bool irq_1(void) = 0; 112 virtual bool irq_2(void) = 0; 113 virtual bool irq_3(void) = 0; 114 115 virtual long counter_value_0(void) = 0; 116 virtual long counter_value_1(void) = 0; 117 virtual long counter_value_2(void) = 0; 118 virtual long counter_value_3(void) = 0; 119 120 void info(void); 121 122 byte_t c_in(byte_t channel); 123 void c_out(byte_t channel, byte_t val); 124 125 void trigger(byte_t channel); 126 void callback(void *data); 127 getIRQVector(byte_t channel)128 byte_t getIRQVector(byte_t channel) 129 { 130 return _irq_vector + 2 * channel; 131 } getIRQ(byte_t channel)132 byte_t getIRQ(byte_t channel) 133 { 134 return (_control[channel] & IRQ) == IRQ_ENABLED; 135 } getTimerValue(byte_t channel)136 word_t getTimerValue(byte_t channel) 137 { 138 return _timer_value[channel]; 139 } isCounter(byte_t channel)140 bool isCounter(byte_t channel) 141 { 142 return ((_control[channel] & MODE) == MODE_COUNTER); 143 } isReset(byte_t channel)144 bool isReset(byte_t channel) 145 { 146 return ((_control[channel] & RESET) == RESET_ACTIVE); 147 } 148 149 /* 150 * InterfaceCircuit 151 */ 152 virtual void reti(void); 153 virtual void irqreq(void); 154 virtual word_t irqack(void); 155 virtual void reset(bool power_on = false); 156 157 virtual void register_callback(int channel, CTCCallbackInterface *cbi); 158 virtual void run_cb_start(int channel); 159 virtual void run_cb_stop(int channel); 160 virtual void run_cb_tc(int channel, long tc); 161 }; 162 163 #endif /* __kc_ctc_h */ 164