r65emu/via.h

99 lines
2.9 KiB
C++

#ifndef _VIA_H
#define _VIA_H
class VIA {
public:
VIA(): _irq(0), _timer1(false), _timer2(false), _t1(0), _t2(0), _t1_latch(0),
_sr(0), _acr(0), _pcr(0), _ier(0), _ifr(0), _ddra(0), _ddrb(0), _porta(0), _portb(0) {}
virtual void reset() {
_timer1 = _timer2 = false;
_t1 = _t2 = _t1_latch = 0;
_sr = _acr = _pcr = _ier = _ifr = _porta = _portb = _ddra = _ddrb = 0;
}
void write(Memory::address, uint8_t);
uint8_t read(Memory::address);
void write_vporta_in_bit(uint8_t, bool);
void write_vportb_in_bit(uint8_t, bool);
void tick();
Line CA2;
void register_irq(Line &irq) { _irq = &irq; }
// acr
static const uint8_t ACR_SHIFT_MASK = 0x1c;
static const uint8_t ACR_T1_SET_PB7 = 0x80;
static const uint8_t ACR_T1_CONTINUOUS = 0x40;
static const uint8_t ACR_T2_COUNT_PB6 = 0x20;
static const uint8_t ACR_SO_T2_RATE = 0x10;
// ier and ifr bits
static const uint8_t INT_MASTER = 0x80;
static const uint8_t INT_TIMER1 = 0x40;
static const uint8_t INT_TIMER2 = 0x20;
static const uint8_t INT_CB1_ACTIVE = 0x10;
static const uint8_t INT_CB2_ACTIVE = 0x08;
static const uint8_t INT_SR = 0x04;
static const uint8_t INT_CA1_ACTIVE = 0x02;
static const uint8_t INT_CA2_ACTIVE = 0x01;
protected:
virtual void write_vportb(uint8_t);
virtual void write_vporta(uint8_t);
virtual void write_vddrb(uint8_t b) { _ddrb = b; }
virtual void write_vddra(uint8_t b) { _ddra = b; }
virtual void write_t1lo(uint8_t b) { write_t1llo(b); }
virtual void write_t1hi(uint8_t);
virtual void write_t1llo(uint8_t);
virtual void write_t1lhi(uint8_t);
virtual void write_t2lo(uint8_t);
virtual void write_t2hi(uint8_t);
virtual void write_sr(uint8_t);
virtual void write_acr(uint8_t b);
virtual void write_pcr(uint8_t b);
virtual void write_ifr(uint8_t b) { _ifr &= ~b; }
virtual void write_ier(uint8_t);
virtual void write_vporta_nh(uint8_t);
virtual uint8_t read_vportb();
virtual uint8_t read_vporta();
virtual uint8_t read_vddrb() { return _ddrb; }
virtual uint8_t read_vddra() { return _ddra; }
virtual uint8_t read_t1lo();
virtual uint8_t read_t1hi() { return _t1 / 0xff; }
virtual uint8_t read_t1llo() { return _t1_latch & 0xff; }
virtual uint8_t read_t1lhi() { return _t1_latch / 0xff; }
virtual uint8_t read_t2lo();
virtual uint8_t read_t2hi() { return _t2 / 0xff; }
virtual uint8_t read_sr();
virtual uint8_t read_acr() { return _acr; }
virtual uint8_t read_pcr() { return _pcr; }
virtual uint8_t read_ifr() { return _ifr; }
virtual uint8_t read_ier() { return _ier | 0x80; }
virtual uint8_t read_vporta_nh();
void set_interrupt() { if (_irq) _irq->set(); }
private:
Line *_irq;
void set_int(uint8_t);
void clear_int(uint8_t);
void start_timer1();
void start_timer2();
volatile bool _timer1, _timer2;
volatile uint16_t _t1, _t2;
uint16_t _t1_latch;
volatile uint32_t _t1_tick, _t2_tick;
uint8_t _sr, _acr, _pcr, _ier, _ifr, _ddra, _ddrb;
volatile uint8_t _porta, _portb;
};
#endif