mirror of
https://github.com/jscrane/r65emu.git
synced 2025-08-06 13:25:26 +00:00
moving away from inheritance from devices
This commit is contained in:
60
src/via.cpp
60
src/via.cpp
@@ -2,8 +2,8 @@
|
|||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <via.h>
|
#include <via.h>
|
||||||
|
|
||||||
#define VPORTB 0x00
|
#define PORTB 0x00
|
||||||
#define VPORTA 0x01
|
#define PORTA 0x01
|
||||||
#define DDRB 0x02
|
#define DDRB 0x02
|
||||||
#define DDRA 0x03
|
#define DDRA 0x03
|
||||||
#define T1LO 0x04
|
#define T1LO 0x04
|
||||||
@@ -17,21 +17,21 @@
|
|||||||
#define PCR 0x0c
|
#define PCR 0x0c
|
||||||
#define IFR 0x0d
|
#define IFR 0x0d
|
||||||
#define IER 0x0e
|
#define IER 0x0e
|
||||||
#define VPORTA_NH 0x0f
|
#define PORTA_NH 0x0f
|
||||||
|
|
||||||
void VIA::write(Memory::address a, uint8_t b) {
|
void VIA::write(Memory::address a, uint8_t b) {
|
||||||
switch (a & 0x0f) {
|
switch (a & 0x0f) {
|
||||||
case VPORTB:
|
case PORTB:
|
||||||
write_vportb(b);
|
write_portb(b);
|
||||||
break;
|
break;
|
||||||
case VPORTA:
|
case PORTA:
|
||||||
write_vporta(b);
|
write_porta(b);
|
||||||
break;
|
break;
|
||||||
case DDRB:
|
case DDRB:
|
||||||
write_vddrb(b);
|
write_ddrb(b);
|
||||||
break;
|
break;
|
||||||
case DDRA:
|
case DDRA:
|
||||||
write_vddra(b);
|
write_ddra(b);
|
||||||
break;
|
break;
|
||||||
case T1LO:
|
case T1LO:
|
||||||
write_t1lo(b);
|
write_t1lo(b);
|
||||||
@@ -66,18 +66,18 @@ void VIA::write(Memory::address a, uint8_t b) {
|
|||||||
case IER:
|
case IER:
|
||||||
write_ier(b);
|
write_ier(b);
|
||||||
break;
|
break;
|
||||||
case VPORTA_NH:
|
case PORTA_NH:
|
||||||
write_vporta_nh(b);
|
write_porta_nh(b);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VIA::write_vportb(uint8_t b) {
|
void VIA::write_portb(uint8_t b) {
|
||||||
_portb = (b & _ddrb);
|
_portb = (b & _ddrb);
|
||||||
clear_int(INT_CB1_ACTIVE | INT_CB2_ACTIVE);
|
clear_int(INT_CB1_ACTIVE | INT_CB2_ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VIA::write_vporta(uint8_t b) {
|
void VIA::write_porta(uint8_t b) {
|
||||||
_porta = (b & _ddra);
|
_porta = (b & _ddra);
|
||||||
clear_int(INT_CA1_ACTIVE | INT_CA2_ACTIVE);
|
clear_int(INT_CA1_ACTIVE | INT_CA2_ACTIVE);
|
||||||
}
|
}
|
||||||
@@ -101,6 +101,8 @@ void VIA::write_t2lo(uint8_t b) {
|
|||||||
_t2 = b;
|
_t2 = b;
|
||||||
_timer2 = false;
|
_timer2 = false;
|
||||||
clear_int(INT_TIMER2);
|
clear_int(INT_TIMER2);
|
||||||
|
if (_t2lo_write_handler)
|
||||||
|
_t2lo_write_handler(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VIA::write_t2hi(uint8_t b) {
|
void VIA::write_t2hi(uint8_t b) {
|
||||||
@@ -112,6 +114,8 @@ void VIA::write_t2hi(uint8_t b) {
|
|||||||
void VIA::write_sr(uint8_t b) {
|
void VIA::write_sr(uint8_t b) {
|
||||||
_sr = b;
|
_sr = b;
|
||||||
clear_int(INT_SR);
|
clear_int(INT_SR);
|
||||||
|
if (_sr_write_handler)
|
||||||
|
_sr_write_handler(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VIA::write_pcr(uint8_t b) {
|
void VIA::write_pcr(uint8_t b) {
|
||||||
@@ -123,6 +127,8 @@ void VIA::write_acr(uint8_t b) {
|
|||||||
_acr = b;
|
_acr = b;
|
||||||
if (b & ACR_T1_CONTINUOUS)
|
if (b & ACR_T1_CONTINUOUS)
|
||||||
start_timer1();
|
start_timer1();
|
||||||
|
if (_acr_write_handler)
|
||||||
|
_acr_write_handler(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VIA::write_ier(uint8_t b) {
|
void VIA::write_ier(uint8_t b) {
|
||||||
@@ -132,20 +138,20 @@ void VIA::write_ier(uint8_t b) {
|
|||||||
_ier &= ~(b & 0x7f);
|
_ier &= ~(b & 0x7f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VIA::write_vporta_nh(uint8_t b) {
|
void VIA::write_porta_nh(uint8_t b) {
|
||||||
_porta = (b & _ddra);
|
_porta = (b & _ddra);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t VIA::read(Memory::address a) {
|
uint8_t VIA::read(Memory::address a) {
|
||||||
switch (a & 0x0f) {
|
switch (a & 0x0f) {
|
||||||
case VPORTB:
|
case PORTB:
|
||||||
return read_vportb();
|
return read_portb();
|
||||||
case VPORTA:
|
case PORTA:
|
||||||
return read_vporta();
|
return read_porta();
|
||||||
case DDRB:
|
case DDRB:
|
||||||
return read_vddrb();
|
return read_ddrb();
|
||||||
case DDRA:
|
case DDRA:
|
||||||
return read_vddra();
|
return read_ddra();
|
||||||
case T1LO:
|
case T1LO:
|
||||||
return read_t1lo();
|
return read_t1lo();
|
||||||
case T1HI:
|
case T1HI:
|
||||||
@@ -168,17 +174,17 @@ uint8_t VIA::read(Memory::address a) {
|
|||||||
return read_ifr();
|
return read_ifr();
|
||||||
case IER:
|
case IER:
|
||||||
return read_ier();
|
return read_ier();
|
||||||
case VPORTA_NH:
|
case PORTA_NH:
|
||||||
return read_vporta_nh();
|
return read_porta_nh();
|
||||||
}
|
}
|
||||||
return 0x00;
|
return 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t VIA::read_vportb() {
|
uint8_t VIA::read_portb() {
|
||||||
return (_portb & _ddrb) | ~_ddrb;
|
return (_portb & _ddrb) | ~_ddrb;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t VIA::read_vporta() {
|
uint8_t VIA::read_porta() {
|
||||||
return (_porta & _ddra) | ~_ddra;
|
return (_porta & _ddra) | ~_ddra;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +203,7 @@ uint8_t VIA::read_sr() {
|
|||||||
return _sr;
|
return _sr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t VIA::read_vporta_nh() {
|
uint8_t VIA::read_porta_nh() {
|
||||||
return (_porta & _ddra) | ~_ddra;
|
return (_porta & _ddra) | ~_ddra;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,14 +245,14 @@ void VIA::clear_int(uint8_t i) {
|
|||||||
_ifr &= ~i;
|
_ifr &= ~i;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VIA::write_vporta_in_bit(uint8_t bit, bool state) {
|
void VIA::write_porta_in_bit(uint8_t bit, bool state) {
|
||||||
if (state)
|
if (state)
|
||||||
_porta |= bit;
|
_porta |= bit;
|
||||||
else
|
else
|
||||||
_porta &= ~bit;
|
_porta &= ~bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VIA::write_vportb_in_bit(uint8_t bit, bool state) {
|
void VIA::write_portb_in_bit(uint8_t bit, bool state) {
|
||||||
if (state)
|
if (state)
|
||||||
_portb |= bit;
|
_portb |= bit;
|
||||||
else
|
else
|
||||||
|
52
src/via.h
52
src/via.h
@@ -15,8 +15,8 @@ public:
|
|||||||
void write(Memory::address, uint8_t);
|
void write(Memory::address, uint8_t);
|
||||||
uint8_t read(Memory::address);
|
uint8_t read(Memory::address);
|
||||||
|
|
||||||
void write_vporta_in_bit(uint8_t, bool);
|
void write_porta_in_bit(uint8_t, bool);
|
||||||
void write_vportb_in_bit(uint8_t, bool);
|
void write_portb_in_bit(uint8_t, bool);
|
||||||
|
|
||||||
void tick();
|
void tick();
|
||||||
|
|
||||||
@@ -28,6 +28,21 @@ public:
|
|||||||
_ca2_handler = fn;
|
_ca2_handler = fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hacks for PET sound
|
||||||
|
void register_sr_write_handler(std::function<void(uint8_t)> fn) {
|
||||||
|
_sr_write_handler = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_acr_write_handler(std::function<void(uint8_t)> fn) {
|
||||||
|
_acr_write_handler = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_t2lo_write_handler(std::function<void(uint8_t)> fn) {
|
||||||
|
_t2lo_write_handler = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_interrupt() { if (_irq_handler) _irq_handler(true); }
|
||||||
|
|
||||||
// acr
|
// acr
|
||||||
static const uint8_t ACR_SHIFT_MASK = 0x1c;
|
static const uint8_t ACR_SHIFT_MASK = 0x1c;
|
||||||
static const uint8_t ACR_T1_SET_PB7 = 0x80;
|
static const uint8_t ACR_T1_SET_PB7 = 0x80;
|
||||||
@@ -46,27 +61,24 @@ public:
|
|||||||
static const uint8_t INT_CA2_ACTIVE = 0x01;
|
static const uint8_t INT_CA2_ACTIVE = 0x01;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void write_vportb(uint8_t);
|
virtual void write_portb(uint8_t);
|
||||||
virtual void write_vporta(uint8_t);
|
virtual void write_porta(uint8_t);
|
||||||
virtual void write_vddrb(uint8_t b) { _ddrb = b; }
|
virtual void write_ddrb(uint8_t b) { _ddrb = b; }
|
||||||
virtual void write_vddra(uint8_t b) { _ddra = b; }
|
virtual void write_ddra(uint8_t b) { _ddra = b; }
|
||||||
virtual void write_t1lo(uint8_t b) { write_t1llo(b); }
|
virtual void write_t1lo(uint8_t b) { write_t1llo(b); }
|
||||||
virtual void write_t1hi(uint8_t);
|
virtual void write_t1hi(uint8_t);
|
||||||
virtual void write_t1llo(uint8_t);
|
virtual void write_t1llo(uint8_t);
|
||||||
virtual void write_t1lhi(uint8_t);
|
virtual void write_t1lhi(uint8_t);
|
||||||
virtual void write_t2lo(uint8_t);
|
|
||||||
virtual void write_t2hi(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_pcr(uint8_t b);
|
||||||
virtual void write_ifr(uint8_t b) { _ifr &= ~b; }
|
virtual void write_ifr(uint8_t b) { _ifr &= ~b; }
|
||||||
virtual void write_ier(uint8_t);
|
virtual void write_ier(uint8_t);
|
||||||
virtual void write_vporta_nh(uint8_t);
|
virtual void write_porta_nh(uint8_t);
|
||||||
|
|
||||||
virtual uint8_t read_vportb();
|
virtual uint8_t read_portb();
|
||||||
virtual uint8_t read_vporta();
|
virtual uint8_t read_porta();
|
||||||
virtual uint8_t read_vddrb() { return _ddrb; }
|
virtual uint8_t read_ddrb() { return _ddrb; }
|
||||||
virtual uint8_t read_vddra() { return _ddra; }
|
virtual uint8_t read_ddra() { return _ddra; }
|
||||||
virtual uint8_t read_t1lo();
|
virtual uint8_t read_t1lo();
|
||||||
virtual uint8_t read_t1hi() { return _t1 / 0xff; }
|
virtual uint8_t read_t1hi() { return _t1 / 0xff; }
|
||||||
virtual uint8_t read_t1llo() { return _t1_latch & 0xff; }
|
virtual uint8_t read_t1llo() { return _t1_latch & 0xff; }
|
||||||
@@ -78,14 +90,20 @@ protected:
|
|||||||
virtual uint8_t read_pcr() { return _pcr; }
|
virtual uint8_t read_pcr() { return _pcr; }
|
||||||
virtual uint8_t read_ifr() { return _ifr; }
|
virtual uint8_t read_ifr() { return _ifr; }
|
||||||
virtual uint8_t read_ier() { return _ier | 0x80; }
|
virtual uint8_t read_ier() { return _ier | 0x80; }
|
||||||
virtual uint8_t read_vporta_nh();
|
virtual uint8_t read_porta_nh();
|
||||||
|
|
||||||
void set_interrupt() { if (_irq_handler) _irq_handler(true); }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void write_sr(uint8_t);
|
||||||
|
void write_acr(uint8_t b);
|
||||||
|
void write_t2lo(uint8_t);
|
||||||
|
|
||||||
std::function<void(bool)> _irq_handler;
|
std::function<void(bool)> _irq_handler;
|
||||||
std::function<void(bool)> _ca2_handler;
|
std::function<void(bool)> _ca2_handler;
|
||||||
|
|
||||||
|
std::function<void(uint8_t)> _sr_write_handler;
|
||||||
|
std::function<void(uint8_t)> _acr_write_handler;
|
||||||
|
std::function<void(uint8_t)> _t2lo_write_handler;
|
||||||
|
|
||||||
void set_int(uint8_t);
|
void set_int(uint8_t);
|
||||||
void clear_int(uint8_t);
|
void clear_int(uint8_t);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user