2018-12-03 22:54:57 +00:00
|
|
|
#include "stdafx.h"
|
|
|
|
#include "M6532.h"
|
|
|
|
|
|
|
|
#include <cassert>
|
|
|
|
|
|
|
|
EightBit::M6532::M6532() noexcept {
|
2019-05-27 12:21:35 +00:00
|
|
|
Ticked.connect([this](EightBit::EventArgs&) {
|
|
|
|
step();
|
|
|
|
});
|
2018-12-03 22:54:57 +00:00
|
|
|
}
|
|
|
|
|
2019-05-27 12:21:35 +00:00
|
|
|
DEFINE_PIN_LEVEL_CHANGERS(RES, M6532);
|
|
|
|
DEFINE_PIN_LEVEL_CHANGERS(RW, M6532);
|
|
|
|
DEFINE_PIN_LEVEL_CHANGERS(IRQ, M6532);
|
|
|
|
DEFINE_PIN_LEVEL_CHANGERS(RS, M6532);
|
|
|
|
DEFINE_PIN_LEVEL_CHANGERS(CS1, M6532);
|
|
|
|
DEFINE_PIN_LEVEL_CHANGERS(CS2, M6532);
|
2018-12-03 22:54:57 +00:00
|
|
|
|
2019-05-27 12:21:35 +00:00
|
|
|
void EightBit::M6532::step() {
|
2018-12-03 22:54:57 +00:00
|
|
|
|
2019-05-27 12:21:35 +00:00
|
|
|
resetCycles();
|
2018-12-03 22:54:57 +00:00
|
|
|
|
2019-05-27 12:21:35 +00:00
|
|
|
if (!activated())
|
|
|
|
return;
|
|
|
|
|
2021-04-07 20:36:53 +00:00
|
|
|
Accessing.fire();
|
2019-05-27 12:21:35 +00:00
|
|
|
|
|
|
|
if (lowered(RES())) {
|
|
|
|
reset();
|
|
|
|
raise(RES());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (--m_currentIncrement == 0) {
|
|
|
|
m_currentIncrement = m_timerIncrement;
|
|
|
|
--m_timerInterval;
|
|
|
|
}
|
|
|
|
|
|
|
|
const bool interruptPA7 = m_allowPA7Interrupts && (PA() & Bit7);
|
|
|
|
if (interruptPA7)
|
2019-11-09 18:58:23 +00:00
|
|
|
IF() = setBit(IF(), Bit6);
|
2019-05-27 12:21:35 +00:00
|
|
|
|
|
|
|
const bool interruptTimer = m_allowTimerInterrupts && (m_timerInterval == 0);
|
|
|
|
if (interruptTimer)
|
2019-11-09 18:58:23 +00:00
|
|
|
IF() = setBit(IF(), Bit7);
|
2019-05-27 12:21:35 +00:00
|
|
|
|
2019-06-02 11:12:04 +00:00
|
|
|
match(IRQ(), !(interruptPA7 || interruptTimer));
|
2019-05-27 12:21:35 +00:00
|
|
|
|
|
|
|
const auto read = raised(RW());
|
|
|
|
const auto write = lowered(RW());
|
|
|
|
assert(read == !write);
|
|
|
|
|
|
|
|
const auto ram = lowered(RS());
|
|
|
|
if (ram) {
|
2018-12-03 22:54:57 +00:00
|
|
|
|
2019-05-27 12:21:35 +00:00
|
|
|
auto& cell = RAM().reference(address() & 0x7f);
|
|
|
|
read ? DATA() = cell : cell = DATA();
|
2018-12-03 22:54:57 +00:00
|
|
|
|
2019-05-27 12:21:35 +00:00
|
|
|
} else {
|
2018-12-03 22:54:57 +00:00
|
|
|
|
2019-05-27 12:21:35 +00:00
|
|
|
const auto a0 = address() & 0b00001;
|
|
|
|
const auto a1 = address() & 0b00010;
|
|
|
|
const auto a2 = address() & 0b00100;
|
|
|
|
const auto a3 = address() & 0b01000;
|
|
|
|
const auto a4 = address() & 0b10000;
|
2018-12-03 22:54:57 +00:00
|
|
|
|
2019-05-27 12:21:35 +00:00
|
|
|
const auto portControls = a2 == 0;
|
|
|
|
const auto otherControls = a2 == 1;
|
|
|
|
|
|
|
|
if (portControls) {
|
|
|
|
|
|
|
|
switch (a0 | a1) {
|
|
|
|
case 0b00:
|
|
|
|
// R/W output reg A
|
|
|
|
break;
|
|
|
|
case 0b01:
|
|
|
|
read ? DATA() = DDRA() : DDRA() = DATA();
|
|
|
|
break;
|
|
|
|
case 0b10:
|
|
|
|
// R/W output reg B
|
|
|
|
break;
|
|
|
|
case 0b11:
|
|
|
|
read ? DATA() = DDRB() : DDRB() = DATA();
|
|
|
|
break;
|
|
|
|
}
|
2018-12-03 22:54:57 +00:00
|
|
|
|
|
|
|
} else {
|
|
|
|
|
2019-05-27 12:21:35 +00:00
|
|
|
if (read && !a4 && a2) {
|
|
|
|
m_allowPA7Interrupts = !a1;
|
|
|
|
m_edgeDetection = a0 ? Positive : Negative;
|
|
|
|
}
|
2018-12-03 22:54:57 +00:00
|
|
|
|
2019-05-27 12:21:35 +00:00
|
|
|
if (read && a2 && a0) {
|
|
|
|
DATA() = IF();
|
2019-11-09 18:58:23 +00:00
|
|
|
IF() = clearBit(IF(), Bit6);
|
2019-05-27 12:21:35 +00:00
|
|
|
}
|
2018-12-03 22:54:57 +00:00
|
|
|
|
2019-05-27 12:21:35 +00:00
|
|
|
m_allowTimerInterrupts = !!a3;
|
2018-12-03 22:54:57 +00:00
|
|
|
|
2019-05-27 12:21:35 +00:00
|
|
|
if (write && a4) {
|
|
|
|
m_timerInterval = DATA();
|
|
|
|
switch (a1 | a0) {
|
2018-12-03 22:54:57 +00:00
|
|
|
case 0b00:
|
2019-05-27 12:21:35 +00:00
|
|
|
m_timerIncrement = One;
|
2018-12-03 22:54:57 +00:00
|
|
|
break;
|
|
|
|
case 0b01:
|
2019-05-27 12:21:35 +00:00
|
|
|
m_timerIncrement = Eight;
|
2018-12-03 22:54:57 +00:00
|
|
|
break;
|
|
|
|
case 0b10:
|
2019-05-27 12:21:35 +00:00
|
|
|
m_timerIncrement = SixtyFour;
|
2018-12-03 22:54:57 +00:00
|
|
|
break;
|
|
|
|
case 0b11:
|
2019-05-27 12:21:35 +00:00
|
|
|
m_timerIncrement = OneThousandAndTwentyFour;
|
2018-12-03 22:54:57 +00:00
|
|
|
break;
|
|
|
|
}
|
2019-05-27 12:21:35 +00:00
|
|
|
m_currentIncrement = m_timerIncrement;
|
2019-11-09 18:58:23 +00:00
|
|
|
IF() = clearBit(IF(), Bit7);
|
2018-12-03 22:54:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-07 20:36:53 +00:00
|
|
|
Accessed.fire();
|
2018-12-03 22:54:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EightBit::M6532::reset() {
|
|
|
|
PA() = m_dra = m_ddra = 0; // Zero port A registers
|
|
|
|
PB() = m_drb = m_ddrb = 0; // Zero port B registers
|
|
|
|
m_allowTimerInterrupts = m_allowPA7Interrupts = false; // Interrupts are disabled
|
|
|
|
}
|