mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-08-13 12:24:58 +00:00
Add support for RD and WR lines to the Z80 emulator.
Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
@@ -86,11 +86,16 @@ namespace EightBit {
|
|||||||
DECLARE_PIN_INPUT(NMI)
|
DECLARE_PIN_INPUT(NMI)
|
||||||
DECLARE_PIN_OUTPUT(M1)
|
DECLARE_PIN_OUTPUT(M1)
|
||||||
DECLARE_PIN_OUTPUT(IORQ)
|
DECLARE_PIN_OUTPUT(IORQ)
|
||||||
|
DECLARE_PIN_OUTPUT(RD)
|
||||||
|
DECLARE_PIN_OUTPUT(WR)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void handleRESET() final;
|
void handleRESET() final;
|
||||||
void handleINT() final;
|
void handleINT() final;
|
||||||
|
|
||||||
|
void busWrite() final;
|
||||||
|
uint8_t busRead() final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
InputOutput& m_ports;
|
InputOutput& m_ports;
|
||||||
|
|
||||||
@@ -191,7 +196,7 @@ namespace EightBit {
|
|||||||
case 5:
|
case 5:
|
||||||
return HL2().low;
|
return HL2().low;
|
||||||
case 6:
|
case 6:
|
||||||
return busRead(UNLIKELY(m_displaced) ? displacedAddress() : HL().word);
|
return IntelProcessor::busRead(UNLIKELY(m_displaced) ? displacedAddress() : HL().word);
|
||||||
case 7:
|
case 7:
|
||||||
return A();
|
return A();
|
||||||
default:
|
default:
|
||||||
@@ -222,7 +227,7 @@ namespace EightBit {
|
|||||||
HL2().low = value;
|
HL2().low = value;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
busWrite(UNLIKELY(m_displaced) ? displacedAddress() : HL().word, value);
|
IntelProcessor::busWrite(UNLIKELY(m_displaced) ? displacedAddress() : HL().word, value);
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
A() = value;
|
A() = value;
|
||||||
@@ -255,7 +260,7 @@ namespace EightBit {
|
|||||||
L() = value;
|
L() = value;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
busWrite(HL(), value);
|
IntelProcessor::busWrite(HL(), value);
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
A() = value;
|
A() = value;
|
||||||
|
@@ -8,6 +8,9 @@ EightBit::Z80::Z80(Bus& bus, InputOutput& ports)
|
|||||||
m_ports(ports) {
|
m_ports(ports) {
|
||||||
RaisedPOWER.connect([this](EventArgs) {
|
RaisedPOWER.connect([this](EventArgs) {
|
||||||
raiseM1();
|
raiseM1();
|
||||||
|
raiseIORQ();
|
||||||
|
raiseRD();
|
||||||
|
raiseWR();
|
||||||
|
|
||||||
di();
|
di();
|
||||||
IM() = 0;
|
IM() = 0;
|
||||||
@@ -31,6 +34,8 @@ EightBit::Z80::Z80(Bus& bus, InputOutput& ports)
|
|||||||
DEFINE_PIN_LEVEL_CHANGERS(NMI, Z80);
|
DEFINE_PIN_LEVEL_CHANGERS(NMI, Z80);
|
||||||
DEFINE_PIN_LEVEL_CHANGERS(M1, Z80);
|
DEFINE_PIN_LEVEL_CHANGERS(M1, Z80);
|
||||||
DEFINE_PIN_LEVEL_CHANGERS(IORQ, Z80);
|
DEFINE_PIN_LEVEL_CHANGERS(IORQ, Z80);
|
||||||
|
DEFINE_PIN_LEVEL_CHANGERS(RD, Z80);
|
||||||
|
DEFINE_PIN_LEVEL_CHANGERS(WR, Z80);
|
||||||
|
|
||||||
EightBit::register16_t& EightBit::Z80::AF() {
|
EightBit::register16_t& EightBit::Z80::AF() {
|
||||||
return m_accumulatorFlags[m_accumulatorFlagsSet];
|
return m_accumulatorFlags[m_accumulatorFlagsSet];
|
||||||
@@ -48,6 +53,19 @@ EightBit::register16_t& EightBit::Z80::HL() {
|
|||||||
return m_registers[m_registerSet][HL_IDX];
|
return m_registers[m_registerSet][HL_IDX];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EightBit::Z80::busWrite() {
|
||||||
|
lowerWR();
|
||||||
|
IntelProcessor::busWrite();
|
||||||
|
raiseWR();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t EightBit::Z80::busRead() {
|
||||||
|
lowerRD();
|
||||||
|
const auto returned = IntelProcessor::busRead();
|
||||||
|
raiseRD();
|
||||||
|
return returned;
|
||||||
|
}
|
||||||
|
|
||||||
void EightBit::Z80::handleRESET() {
|
void EightBit::Z80::handleRESET() {
|
||||||
IntelProcessor::handleRESET();
|
IntelProcessor::handleRESET();
|
||||||
di();
|
di();
|
||||||
@@ -489,19 +507,19 @@ void EightBit::Z80::ccf() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::xhtl(register16_t& exchange) {
|
void EightBit::Z80::xhtl(register16_t& exchange) {
|
||||||
MEMPTR().low = busRead(SP());
|
MEMPTR().low = IntelProcessor::busRead(SP());
|
||||||
++BUS().ADDRESS();
|
++BUS().ADDRESS();
|
||||||
MEMPTR().high = busRead();
|
MEMPTR().high = IntelProcessor::busRead();
|
||||||
busWrite(exchange.high);
|
IntelProcessor::busWrite(exchange.high);
|
||||||
exchange.high = MEMPTR().high;
|
exchange.high = MEMPTR().high;
|
||||||
--BUS().ADDRESS();
|
--BUS().ADDRESS();
|
||||||
busWrite(exchange.low);
|
IntelProcessor::busWrite(exchange.low);
|
||||||
exchange.low = MEMPTR().low;
|
exchange.low = MEMPTR().low;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::blockCompare(const register16_t source, register16_t& counter) {
|
void EightBit::Z80::blockCompare(const register16_t source, register16_t& counter) {
|
||||||
|
|
||||||
const auto value = busRead(source);
|
const auto value = IntelProcessor::busRead(source);
|
||||||
uint8_t result = A() - value;
|
uint8_t result = A() - value;
|
||||||
|
|
||||||
setFlag(F(), PF, --counter.word);
|
setFlag(F(), PF, --counter.word);
|
||||||
@@ -537,8 +555,8 @@ bool EightBit::Z80::cpdr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::blockLoad(const register16_t source, const register16_t destination, register16_t& counter) {
|
void EightBit::Z80::blockLoad(const register16_t source, const register16_t destination, register16_t& counter) {
|
||||||
const auto value = busRead(source);
|
const auto value = IntelProcessor::busRead(source);
|
||||||
busWrite(destination, value);
|
IntelProcessor::busWrite(destination, value);
|
||||||
const auto xy = A() + value;
|
const auto xy = A() + value;
|
||||||
setFlag(F(), XF, xy & Bit3);
|
setFlag(F(), XF, xy & Bit3);
|
||||||
setFlag(F(), YF, xy & Bit1);
|
setFlag(F(), YF, xy & Bit1);
|
||||||
@@ -567,7 +585,7 @@ bool EightBit::Z80::lddr() {
|
|||||||
void EightBit::Z80::blockIn(register16_t& source, const register16_t destination) {
|
void EightBit::Z80::blockIn(register16_t& source, const register16_t destination) {
|
||||||
MEMPTR() = BUS().ADDRESS() = source;
|
MEMPTR() = BUS().ADDRESS() = source;
|
||||||
const auto value = readPort();
|
const auto value = readPort();
|
||||||
busWrite(destination, value);
|
IntelProcessor::busWrite(destination, value);
|
||||||
source.high = decrement(source.high);
|
source.high = decrement(source.high);
|
||||||
setFlag(F(), NF);
|
setFlag(F(), NF);
|
||||||
}
|
}
|
||||||
@@ -593,7 +611,7 @@ bool EightBit::Z80::indr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::blockOut(const register16_t source, register16_t& destination) {
|
void EightBit::Z80::blockOut(const register16_t source, register16_t& destination) {
|
||||||
const auto value = busRead(source);
|
const auto value = IntelProcessor::busRead(source);
|
||||||
destination.high = decrement(destination.high);
|
destination.high = decrement(destination.high);
|
||||||
BUS().ADDRESS() = destination;
|
BUS().ADDRESS() = destination;
|
||||||
writePort();
|
writePort();
|
||||||
@@ -626,7 +644,7 @@ bool EightBit::Z80::otdr() {
|
|||||||
void EightBit::Z80::rrd() {
|
void EightBit::Z80::rrd() {
|
||||||
(MEMPTR() = BUS().ADDRESS() = HL())++;
|
(MEMPTR() = BUS().ADDRESS() = HL())++;
|
||||||
const auto memory = busRead();
|
const auto memory = busRead();
|
||||||
busWrite(promoteNibble(A()) | highNibble(memory));
|
IntelProcessor::busWrite(promoteNibble(A()) | highNibble(memory));
|
||||||
A() = higherNibble(A()) | lowerNibble(memory);
|
A() = higherNibble(A()) | lowerNibble(memory);
|
||||||
adjustSZPXY<Z80>(F(), A());
|
adjustSZPXY<Z80>(F(), A());
|
||||||
clearFlag(F(), NF | HC);
|
clearFlag(F(), NF | HC);
|
||||||
@@ -635,7 +653,7 @@ void EightBit::Z80::rrd() {
|
|||||||
void EightBit::Z80::rld() {
|
void EightBit::Z80::rld() {
|
||||||
(MEMPTR() = BUS().ADDRESS() = HL())++;
|
(MEMPTR() = BUS().ADDRESS() = HL())++;
|
||||||
const auto memory = busRead();
|
const auto memory = busRead();
|
||||||
busWrite(promoteNibble(memory) | lowNibble(A()));
|
IntelProcessor::busWrite(promoteNibble(memory) | lowNibble(A()));
|
||||||
A() = higherNibble(A()) | highNibble(memory);
|
A() = higherNibble(A()) | highNibble(memory);
|
||||||
adjustSZPXY<Z80>(F(), A());
|
adjustSZPXY<Z80>(F(), A());
|
||||||
clearFlag(F(), NF | HC);
|
clearFlag(F(), NF | HC);
|
||||||
@@ -649,7 +667,11 @@ void EightBit::Z80::writePort(const uint8_t port) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Z80::writePort() {
|
void EightBit::Z80::writePort() {
|
||||||
|
lowerIORQ();
|
||||||
|
lowerWR();
|
||||||
m_ports.write(BUS().ADDRESS().low, BUS().DATA());
|
m_ports.write(BUS().ADDRESS().low, BUS().DATA());
|
||||||
|
raiseWR();
|
||||||
|
raiseIORQ();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::Z80::readPort(const uint8_t port) {
|
uint8_t EightBit::Z80::readPort(const uint8_t port) {
|
||||||
@@ -659,7 +681,12 @@ uint8_t EightBit::Z80::readPort(const uint8_t port) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::Z80::readPort() {
|
uint8_t EightBit::Z80::readPort() {
|
||||||
return BUS().DATA() = m_ports.read(BUS().ADDRESS().low);
|
lowerIORQ();
|
||||||
|
lowerRD();
|
||||||
|
const auto returned = BUS().DATA() = m_ports.read(BUS().ADDRESS().low);
|
||||||
|
raiseRD();
|
||||||
|
raiseIORQ();
|
||||||
|
return returned;
|
||||||
}
|
}
|
||||||
|
|
||||||
int EightBit::Z80::step() {
|
int EightBit::Z80::step() {
|
||||||
@@ -721,7 +748,7 @@ void EightBit::Z80::executeCB(const int x, const int y, const int z) {
|
|||||||
const bool memoryY = y == 6;
|
const bool memoryY = y == 6;
|
||||||
const bool memoryZ = z == 6;
|
const bool memoryZ = z == 6;
|
||||||
const bool indirect = (!m_displaced && memoryZ) || m_displaced;
|
const bool indirect = (!m_displaced && memoryZ) || m_displaced;
|
||||||
auto operand = m_displaced ? busRead(displacedAddress()) : R(z);
|
auto operand = m_displaced ? IntelProcessor::busRead(displacedAddress()) : R(z);
|
||||||
const bool update = x != 1; // BIT does not update
|
const bool update = x != 1; // BIT does not update
|
||||||
switch (x) {
|
switch (x) {
|
||||||
case 0: { // rot[y] r[z]
|
case 0: { // rot[y] r[z]
|
||||||
@@ -779,7 +806,7 @@ void EightBit::Z80::executeCB(const int x, const int y, const int z) {
|
|||||||
}
|
}
|
||||||
if (update) {
|
if (update) {
|
||||||
if (m_displaced) {
|
if (m_displaced) {
|
||||||
busWrite(operand);
|
IntelProcessor::busWrite(operand);
|
||||||
if (!memoryZ)
|
if (!memoryZ)
|
||||||
R2(z, operand);
|
R2(z, operand);
|
||||||
tick(15);
|
tick(15);
|
||||||
|
Reference in New Issue
Block a user