mirror of
https://github.com/jscrane/r65emu.git
synced 2025-08-07 20:25:03 +00:00
@@ -77,6 +77,10 @@ void hardware_init(CPU &cpu) {
|
||||
delay(800);
|
||||
#endif
|
||||
|
||||
#if defined(PWM_SOUND)
|
||||
pinMode(PWM_SOUND, OUTPUT);
|
||||
#endif
|
||||
|
||||
#if defined(TFT_BACKLIGHT)
|
||||
pinMode(TFT_BACKLIGHT, OUTPUT);
|
||||
#endif
|
||||
@@ -131,6 +135,10 @@ int hardware_oneshot_timer(uint32_t interval, std::function<void(void)> cb) {
|
||||
return timers.setTimeout(interval, cb);
|
||||
}
|
||||
|
||||
void hardware_cancel_timer(int timer) {
|
||||
timers.deleteTimer(timer);
|
||||
}
|
||||
|
||||
#if !defined(NO_CHECKPOINT)
|
||||
void hardware_checkpoint(Stream &s) {
|
||||
unsigned ds = 0;
|
||||
|
@@ -20,8 +20,9 @@ void hardware_checkpoint(class Stream &);
|
||||
void hardware_restore(class Stream &);
|
||||
bool hardware_run(unsigned instructions = CPU_INSTRUCTIONS);
|
||||
bool hardware_debug_cpu();
|
||||
int hardware_interval_timer(uint32_t ms, std::function<void(void)> cb);
|
||||
int hardware_oneshot_timer(uint32_t ms, std::function<void(void)> cb);
|
||||
int hardware_interval_timer(uint32_t dt, std::function<void(void)> cb);
|
||||
int hardware_oneshot_timer(uint32_t dt, std::function<void(void)> cb);
|
||||
void hardware_cancel_timer(int timer);
|
||||
|
||||
#if defined(__SPIRAM_H__) && defined(USE_SPIRAM)
|
||||
extern class spiram sram;
|
||||
|
28
src/via.cpp
28
src/via.cpp
@@ -122,10 +122,9 @@ void VIA::write_t1hi(uint8_t b) {
|
||||
|
||||
void VIA::write_t2lo(uint8_t b) {
|
||||
_t2 = b;
|
||||
_t2_ll = b;
|
||||
_timer2 = false;
|
||||
clear_int(INT_TIMER2);
|
||||
if (_t2lo_write_handler)
|
||||
_t2lo_write_handler(b);
|
||||
}
|
||||
|
||||
void VIA::write_t2hi(uint8_t b) {
|
||||
@@ -137,8 +136,8 @@ void VIA::write_t2hi(uint8_t b) {
|
||||
void VIA::write_sr(uint8_t b) {
|
||||
_sr = b;
|
||||
clear_int(INT_SR);
|
||||
if (_sr_write_handler)
|
||||
_sr_write_handler(b);
|
||||
if (_acr & ACR_SO_T2_RATE)
|
||||
start_sr_timer();
|
||||
}
|
||||
|
||||
void VIA::write_pcr(uint8_t b) {
|
||||
@@ -148,10 +147,8 @@ void VIA::write_pcr(uint8_t b) {
|
||||
|
||||
void VIA::write_acr(uint8_t b) {
|
||||
_acr = b;
|
||||
if (b & ACR_T1_CONTINUOUS)
|
||||
if (_acr & ACR_T1_CONTINUOUS)
|
||||
start_timer1();
|
||||
if (_acr_write_handler)
|
||||
_acr_write_handler(b);
|
||||
}
|
||||
|
||||
void VIA::write_ier(uint8_t b) {
|
||||
@@ -304,3 +301,20 @@ void VIA::start_timer2() {
|
||||
_t2_expiry = micros() + _t2;
|
||||
_timer2 = true;
|
||||
}
|
||||
|
||||
void VIA::start_sr_timer() {
|
||||
if (_sr_timer < 0)
|
||||
_sr_timer = hardware_oneshot_timer(2*_t2_ll + 2, [this]() {
|
||||
shift_out();
|
||||
_sr_timer = -1;
|
||||
if (_acr & ACR_SO_T2_RATE)
|
||||
start_sr_timer();
|
||||
});
|
||||
}
|
||||
|
||||
void VIA::shift_out() {
|
||||
uint8_t cb2 = (_sr >> 7) & 1;
|
||||
_sr = (_sr << 1) | cb2;
|
||||
if (_cb2_handler)
|
||||
_cb2_handler(cb2);
|
||||
}
|
||||
|
33
src/via.h
33
src/via.h
@@ -9,6 +9,8 @@ public:
|
||||
_timer1 = _timer2 = false;
|
||||
_t1 = _t1_latch = 0xdfff;
|
||||
_t2 = 0xffff;
|
||||
_sr_timer = -1;
|
||||
_t2_ll = 0xff;
|
||||
_sr = _acr = _pcr = _ier = _ifr = _porta = _portb = _ddra = _ddrb = 0;
|
||||
}
|
||||
|
||||
@@ -28,17 +30,8 @@ public:
|
||||
_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 register_cb2_handler(std::function<void(bool)> fn) {
|
||||
_cb2_handler = fn;
|
||||
}
|
||||
|
||||
void set_interrupt() { if (_irq_handler) _irq_handler(true); }
|
||||
@@ -94,26 +87,28 @@ protected:
|
||||
|
||||
private:
|
||||
void write_sr(uint8_t);
|
||||
void write_acr(uint8_t b);
|
||||
void write_acr(uint8_t);
|
||||
void write_t2lo(uint8_t);
|
||||
|
||||
std::function<void(bool)> _irq_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;
|
||||
std::function<void(bool)> _cb2_handler;
|
||||
|
||||
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;
|
||||
bool _timer1, _timer2;
|
||||
uint16_t _t1, _t2;
|
||||
uint16_t _t1_latch;
|
||||
uint32_t _t1_expiry, _t2_expiry;
|
||||
|
||||
void start_sr_timer();
|
||||
void shift_out();
|
||||
uint8_t _t2_ll;
|
||||
int _sr_timer;
|
||||
|
||||
uint8_t _sr, _acr, _pcr, _ier, _ifr, _ddra, _ddrb;
|
||||
volatile uint8_t _porta, _portb;
|
||||
uint8_t _porta, _portb;
|
||||
};
|
||||
|
Reference in New Issue
Block a user