mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2024-12-22 09:30:32 +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:
parent
6d6c95f695
commit
1ba238bfc7
@ -86,11 +86,16 @@ namespace EightBit {
|
||||
DECLARE_PIN_INPUT(NMI)
|
||||
DECLARE_PIN_OUTPUT(M1)
|
||||
DECLARE_PIN_OUTPUT(IORQ)
|
||||
DECLARE_PIN_OUTPUT(RD)
|
||||
DECLARE_PIN_OUTPUT(WR)
|
||||
|
||||
protected:
|
||||
void handleRESET() final;
|
||||
void handleINT() final;
|
||||
|
||||
void busWrite() final;
|
||||
uint8_t busRead() final;
|
||||
|
||||
private:
|
||||
InputOutput& m_ports;
|
||||
|
||||
@ -191,7 +196,7 @@ namespace EightBit {
|
||||
case 5:
|
||||
return HL2().low;
|
||||
case 6:
|
||||
return busRead(UNLIKELY(m_displaced) ? displacedAddress() : HL().word);
|
||||
return IntelProcessor::busRead(UNLIKELY(m_displaced) ? displacedAddress() : HL().word);
|
||||
case 7:
|
||||
return A();
|
||||
default:
|
||||
@ -222,7 +227,7 @@ namespace EightBit {
|
||||
HL2().low = value;
|
||||
break;
|
||||
case 6:
|
||||
busWrite(UNLIKELY(m_displaced) ? displacedAddress() : HL().word, value);
|
||||
IntelProcessor::busWrite(UNLIKELY(m_displaced) ? displacedAddress() : HL().word, value);
|
||||
break;
|
||||
case 7:
|
||||
A() = value;
|
||||
@ -255,7 +260,7 @@ namespace EightBit {
|
||||
L() = value;
|
||||
break;
|
||||
case 6:
|
||||
busWrite(HL(), value);
|
||||
IntelProcessor::busWrite(HL(), value);
|
||||
break;
|
||||
case 7:
|
||||
A() = value;
|
||||
|
@ -8,6 +8,9 @@ EightBit::Z80::Z80(Bus& bus, InputOutput& ports)
|
||||
m_ports(ports) {
|
||||
RaisedPOWER.connect([this](EventArgs) {
|
||||
raiseM1();
|
||||
raiseIORQ();
|
||||
raiseRD();
|
||||
raiseWR();
|
||||
|
||||
di();
|
||||
IM() = 0;
|
||||
@ -31,6 +34,8 @@ EightBit::Z80::Z80(Bus& bus, InputOutput& ports)
|
||||
DEFINE_PIN_LEVEL_CHANGERS(NMI, Z80);
|
||||
DEFINE_PIN_LEVEL_CHANGERS(M1, 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() {
|
||||
return m_accumulatorFlags[m_accumulatorFlagsSet];
|
||||
@ -48,6 +53,19 @@ EightBit::register16_t& EightBit::Z80::HL() {
|
||||
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() {
|
||||
IntelProcessor::handleRESET();
|
||||
di();
|
||||
@ -489,19 +507,19 @@ void EightBit::Z80::ccf() {
|
||||
}
|
||||
|
||||
void EightBit::Z80::xhtl(register16_t& exchange) {
|
||||
MEMPTR().low = busRead(SP());
|
||||
MEMPTR().low = IntelProcessor::busRead(SP());
|
||||
++BUS().ADDRESS();
|
||||
MEMPTR().high = busRead();
|
||||
busWrite(exchange.high);
|
||||
MEMPTR().high = IntelProcessor::busRead();
|
||||
IntelProcessor::busWrite(exchange.high);
|
||||
exchange.high = MEMPTR().high;
|
||||
--BUS().ADDRESS();
|
||||
busWrite(exchange.low);
|
||||
IntelProcessor::busWrite(exchange.low);
|
||||
exchange.low = MEMPTR().low;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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) {
|
||||
const auto value = busRead(source);
|
||||
busWrite(destination, value);
|
||||
const auto value = IntelProcessor::busRead(source);
|
||||
IntelProcessor::busWrite(destination, value);
|
||||
const auto xy = A() + value;
|
||||
setFlag(F(), XF, xy & Bit3);
|
||||
setFlag(F(), YF, xy & Bit1);
|
||||
@ -567,7 +585,7 @@ bool EightBit::Z80::lddr() {
|
||||
void EightBit::Z80::blockIn(register16_t& source, const register16_t destination) {
|
||||
MEMPTR() = BUS().ADDRESS() = source;
|
||||
const auto value = readPort();
|
||||
busWrite(destination, value);
|
||||
IntelProcessor::busWrite(destination, value);
|
||||
source.high = decrement(source.high);
|
||||
setFlag(F(), NF);
|
||||
}
|
||||
@ -593,7 +611,7 @@ bool EightBit::Z80::indr() {
|
||||
}
|
||||
|
||||
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);
|
||||
BUS().ADDRESS() = destination;
|
||||
writePort();
|
||||
@ -626,7 +644,7 @@ bool EightBit::Z80::otdr() {
|
||||
void EightBit::Z80::rrd() {
|
||||
(MEMPTR() = BUS().ADDRESS() = HL())++;
|
||||
const auto memory = busRead();
|
||||
busWrite(promoteNibble(A()) | highNibble(memory));
|
||||
IntelProcessor::busWrite(promoteNibble(A()) | highNibble(memory));
|
||||
A() = higherNibble(A()) | lowerNibble(memory);
|
||||
adjustSZPXY<Z80>(F(), A());
|
||||
clearFlag(F(), NF | HC);
|
||||
@ -635,7 +653,7 @@ void EightBit::Z80::rrd() {
|
||||
void EightBit::Z80::rld() {
|
||||
(MEMPTR() = BUS().ADDRESS() = HL())++;
|
||||
const auto memory = busRead();
|
||||
busWrite(promoteNibble(memory) | lowNibble(A()));
|
||||
IntelProcessor::busWrite(promoteNibble(memory) | lowNibble(A()));
|
||||
A() = higherNibble(A()) | highNibble(memory);
|
||||
adjustSZPXY<Z80>(F(), A());
|
||||
clearFlag(F(), NF | HC);
|
||||
@ -649,7 +667,11 @@ void EightBit::Z80::writePort(const uint8_t port) {
|
||||
}
|
||||
|
||||
void EightBit::Z80::writePort() {
|
||||
lowerIORQ();
|
||||
lowerWR();
|
||||
m_ports.write(BUS().ADDRESS().low, BUS().DATA());
|
||||
raiseWR();
|
||||
raiseIORQ();
|
||||
}
|
||||
|
||||
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() {
|
||||
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() {
|
||||
@ -721,7 +748,7 @@ void EightBit::Z80::executeCB(const int x, const int y, const int z) {
|
||||
const bool memoryY = y == 6;
|
||||
const bool memoryZ = z == 6;
|
||||
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
|
||||
switch (x) {
|
||||
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 (m_displaced) {
|
||||
busWrite(operand);
|
||||
IntelProcessor::busWrite(operand);
|
||||
if (!memoryZ)
|
||||
R2(z, operand);
|
||||
tick(15);
|
||||
|
Loading…
Reference in New Issue
Block a user