Wire the MC6850 chip into the MC6809 test code.

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2018-09-23 13:14:10 +01:00
parent 754fc8e6a3
commit b3faa0bb2e
5 changed files with 124 additions and 61 deletions

View File

@ -23,13 +23,16 @@ void Board::initialise() {
CPU().ExecutedInstruction.connect(std::bind(&Board::Cpu_ExecutedInstruction_die, this, std::placeholders::_1)); CPU().ExecutedInstruction.connect(std::bind(&Board::Cpu_ExecutedInstruction_die, this, std::placeholders::_1));
//WrittenByte.connect(std::bind(&Board::Bus_WrittenByte, this, std::placeholders::_1)); WritingByte.connect(std::bind(&Board::Bus_WritingByte_Acia, this, std::placeholders::_1));
//ReadingByte.connect(std::bind(&Board::Bus_ReadingByte, this, std::placeholders::_1)); ReadingByte.connect(std::bind(&Board::Bus_ReadingByte_Acia, this, std::placeholders::_1));
CPU().ExecutedInstruction.connect(std::bind(&Board::Cpu_ExecutedInstruction_Acia, this, std::placeholders::_1));
CPU().powerOn(); CPU().powerOn();
CPU().raise(CPU().NMI()); CPU().raise(CPU().NMI());
CPU().raise(CPU().FIRQ()); CPU().raise(CPU().FIRQ());
CPU().reset(); CPU().reset();
ACIA().powerOn();
} }
void Board::Cpu_ExecutingInstruction_Debug(EightBit::mc6809&) { void Board::Cpu_ExecutingInstruction_Debug(EightBit::mc6809&) {
@ -42,25 +45,10 @@ void Board::Cpu_ExecutedInstruction_Debug(EightBit::mc6809&) {
std::cout << m_disassembler.trace(m_disassembleAt) << std::endl; std::cout << m_disassembler.trace(m_disassembleAt) << std::endl;
} }
void Board::Cpu_ExecutedInstruction_die(EightBit::mc6809& cpu) { void Board::Cpu_ExecutedInstruction_die(EightBit::mc6809&) {
static uint64_t instructions = 0UL; static uint64_t instructions = 0UL;
if (++instructions > 90000000) if (++instructions > 90000000)
cpu.powerOff(); CPU().powerOff();
}
void Board::Bus_WrittenByte(EightBit::EventArgs&) {
if ((ADDRESS().word > 0x9fff) && (ADDRESS().word < 0xc000))
std::cout << std::hex << "** IO wrote " << DATA() << " to " << ADDRESS() << std::endl;
}
void Board::Bus_ReadingByte(EightBit::EventArgs&) {
if ((ADDRESS().word > 0x9fff) && (ADDRESS().word < 0xc000)) {
std::cout << std::hex << "** IO reading " << ADDRESS() << std::endl;
switch (ADDRESS().word) {
case 0xa000:
poke(ADDRESS(), 0x03);
}
}
} }
EightBit::MemoryMapping Board::mapping(uint16_t address) { EightBit::MemoryMapping Board::mapping(uint16_t address) {
@ -76,3 +64,25 @@ EightBit::MemoryMapping Board::mapping(uint16_t address) {
return { m_rom, 0xc000, EightBit::MemoryMapping::ReadOnly }; return { m_rom, 0xc000, EightBit::MemoryMapping::ReadOnly };
} }
void Board::Bus_WritingByte_Acia(EightBit::EventArgs&) {
ACIA().RW() = EightBit::Chip::Low;
updateAciaPins();
}
void Board::Bus_ReadingByte_Acia(EightBit::EventArgs&) {
ACIA().RW() = EightBit::Chip::High;
updateAciaPins();
}
void Board::updateAciaPins() {
ACIA().DATA() = DATA();
ACIA().RS() = ADDRESS().word & EightBit::Chip::Bit0 ? EightBit::Chip::PinLevel::High : EightBit::Chip::PinLevel::Low;
ACIA().CS0() = ADDRESS().word & EightBit::Chip::Bit15 ? EightBit::Chip::PinLevel::High : EightBit::Chip::PinLevel::Low;
ACIA().CS1() = ADDRESS().word & EightBit::Chip::Bit13 ? EightBit::Chip::PinLevel::High : EightBit::Chip::PinLevel::Low;
ACIA().CS2() = ADDRESS().word & EightBit::Chip::Bit14 ? EightBit::Chip::PinLevel::High : EightBit::Chip::PinLevel::Low;
}
void Board::Cpu_ExecutedInstruction_Acia(EightBit::mc6809&) {
ACIA().step(CPU().cycles());
}

View File

@ -8,12 +8,14 @@
#include <Bus.h> #include <Bus.h>
#include <mc6809.h> #include <mc6809.h>
#include <Disassembly.h> #include <Disassembly.h>
#include <MC6850.h>
class Board : public EightBit::Bus { class Board : public EightBit::Bus {
public: public:
Board(const Configuration& configuration); Board(const Configuration& configuration);
EightBit::mc6809& CPU() { return m_cpu; } EightBit::mc6809& CPU() { return m_cpu; }
EightBit::mc6850& ACIA() { return m_acia; }
void initialise(); void initialise();
@ -36,6 +38,8 @@ private:
EightBit::Ram m_io = 0x2000; // A000 - BFFF, 8K serial interface, minimally decoded EightBit::Ram m_io = 0x2000; // A000 - BFFF, 8K serial interface, minimally decoded
EightBit::Rom m_rom = 0x4000; // C000 - FFFF, 16K ROM EightBit::Rom m_rom = 0x4000; // C000 - FFFF, 16K ROM
EightBit::mc6850 m_acia;
EightBit::mc6809 m_cpu; EightBit::mc6809 m_cpu;
EightBit::Disassembly m_disassembler; EightBit::Disassembly m_disassembler;
@ -47,8 +51,14 @@ private:
void Cpu_ExecutingInstruction_Debug(EightBit::mc6809& cpu); void Cpu_ExecutingInstruction_Debug(EightBit::mc6809& cpu);
void Cpu_ExecutedInstruction_Debug(EightBit::mc6809& cpu); void Cpu_ExecutedInstruction_Debug(EightBit::mc6809& cpu);
void Cpu_ExecutedInstruction_die(EightBit::mc6809& cpu); void Cpu_ExecutedInstruction_die(EightBit::mc6809&);
void Bus_WrittenByte(EightBit::EventArgs&); // ACIA handling
void Bus_ReadingByte(EightBit::EventArgs&);
void Bus_WritingByte_Acia(EightBit::EventArgs&);
void Bus_ReadingByte_Acia(EightBit::EventArgs&);
void Cpu_ExecutedInstruction_Acia(EightBit::mc6809&);
void updateAciaPins();
}; };

View File

@ -71,19 +71,19 @@
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<IncludePath>..\inc;..\..\inc;C:\Libraries\boost_1_65_1;$(IncludePath)</IncludePath> <IncludePath>..\inc;..\..\inc;..\..\MC6850\inc;C:\Libraries\boost_1_65_1;$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<IncludePath>..\inc;..\..\inc;C:\Libraries\boost_1_65_1;$(IncludePath)</IncludePath> <IncludePath>..\inc;..\..\inc;..\..\MC6850\inc;C:\Libraries\boost_1_65_1;$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<IncludePath>..\inc;..\..\inc;C:\Libraries\boost_1_65_1;$(IncludePath)</IncludePath> <IncludePath>..\inc;..\..\inc;..\..\MC6850\inc;C:\Libraries\boost_1_65_1;$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<IncludePath>..\inc;..\..\inc;C:\Libraries\boost_1_65_1;$(IncludePath)</IncludePath> <IncludePath>..\inc;..\..\inc;..\..\MC6850\inc;C:\Libraries\boost_1_65_1;$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
@ -167,6 +167,9 @@
<ClCompile Include="test.cpp" /> <ClCompile Include="test.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\MC6850\src\MC6850.vcxproj">
<Project>{a4ada650-55c3-4c00-8dad-e4e4aff86eff}</Project>
</ProjectReference>
<ProjectReference Include="..\..\src\EightBit.vcxproj"> <ProjectReference Include="..\..\src\EightBit.vcxproj">
<Project>{a9c24bd9-0cb4-4c84-b09b-46b815f9da47}</Project> <Project>{a9c24bd9-0cb4-4c84-b09b-46b815f9da47}</Project>
</ProjectReference> </ProjectReference>

View File

@ -2,10 +2,10 @@
#include <cstdint> #include <cstdint>
#include <Processor.h> #include <Chip.h>
namespace EightBit { namespace EightBit {
class mc6850 { class mc6850 : public Chip {
public: public:
// +--------+----------------------------------------------------------------------------------+ // +--------+----------------------------------------------------------------------------------+
// | | Buffer address | // | | Buffer address |
@ -14,7 +14,7 @@ namespace EightBit {
// | Data | RS * R/W | RS * R/W | RS * R/W | RS * R/W | // | Data | RS * R/W | RS * R/W | RS * R/W | RS * R/W |
// | Bus | (high)(low) | (high)(high) | (low)(low) | (low)(low) | // | Bus | (high)(low) | (high)(high) | (low)(low) | (low)(low) |
// | Line | Transmit | Receive | | | // | Line | Transmit | Receive | | |
// | Number | Data | Data | Control | Control | // | Number | Data | Data | Control | Status |
// | | Register | Register | register | register | // | | Register | Register | register | register |
// | +------------------+------------------+--------------------+-----------------------+ // | +------------------+------------------+--------------------+-----------------------+
// | | (Write only) + (Read only) + (Write only) | (Read only) | // | | (Write only) + (Read only) + (Write only) | (Read only) |
@ -47,49 +47,89 @@ namespace EightBit {
// ** Data bit will be zero in 7-bit plus parity modes // ** Data bit will be zero in 7-bit plus parity modes
// *** Data bit is "don't case" in 7-bit plus parity modes // *** Data bit is "don't case" in 7-bit plus parity modes
Processor::PinLevel& RXDATA() { return m_RXDATA; } // Receive data, (I) Active high enum ControlRegisters {
Processor::PinLevel& TXDATA() { return m_TXDATA; } // Transmit data, (O) Active high CR0 = 0b1,
CR1 = 0b10,
CR2 = 0b100,
CR3 = 0b1000,
CR4 = 0b10000,
CR5 = 0b100000,
CR6 = 0b1000000,
CR7 = 0b10000000
};
Processor::PinLevel& RTS() { return m_RTS; } // Request to send, (O) Active low enum StatusRegisters {
Processor::PinLevel& CTS() { return m_CTS; } // Clear to send, (I) Active low RDRF = 0b1,
Processor::PinLevel& DCD() { return m_DCD; } // Data carrier detect, (I) Active low TDRE = 0b10,
kDCD = 0b100,
kCTS = 0b1000,
FE = 0b10000,
OVRN = 0b100000,
PE = 0b1000000,
kIRQ = 0b10000000,
};
Processor::PinLevel& RXCLK() { return m_RXCLK; } // Transmit clock, (I) Active high PinLevel& RXDATA() { return m_RXDATA; } // Receive data, (I) Active high
Processor::PinLevel& TXCLK() { return m_TXCLK; } // Receive clock, (I) Active high PinLevel& TXDATA() { return m_TXDATA; } // Transmit data, (O) Active high
PinLevel& RTS() { return m_RTS; } // Request to send, (O) Active low
PinLevel& CTS() { return m_CTS; } // Clear to send, (I) Active low
PinLevel& DCD() { return m_DCD; } // Data carrier detect, (I) Active low
PinLevel& RXCLK() { return m_RXCLK; } // Transmit clock, (I) Active high
PinLevel& TXCLK() { return m_TXCLK; } // Receive clock, (I) Active high
PinLevel& CS0() { return m_CS0; } // Chip select, bit 0, (I) Active high
PinLevel& CS1() { return m_CS1; } // Chip select, bit 1, (I) Active high
PinLevel& CS2() { return m_CS2; } // Chip select, bit 2, (I) Active low
PinLevel& RS() { return m_RS; } // Register select, (I) Active high
PinLevel& RW() { return m_RW; } // Read/Write, (I) Read high, write low
PinLevel& E() { return m_E; } // ACIA Enable, (I) Active high
PinLevel& IRQ() { return m_IRQ; } // Interrupt request, (O) Active low
uint8_t& DATA() { return m_data; } // Data, (I/O) uint8_t& DATA() { return m_data; } // Data, (I/O)
Processor::PinLevel& CS0() { return m_CS0; } // Chip select, bit 0, (I) Active high void step(int cycles);
Processor::PinLevel& CS1() { return m_CS1; } // Chip select, bit 1, (I) Active high
Processor::PinLevel& CS2() { return m_CS2; } // Chip select, bit 2, (I) Active low
Processor::PinLevel& RS() { return m_RS; } // Register select, (I) Active high
Processor::PinLevel& RW() { return m_RW; } // Read/Write, (I) Read high, write low
Processor::PinLevel& E() { return m_E; } // ACIA Enable, (I) Active high
Processor::PinLevel& IRQ() { return m_IRQ; } // Interrupt request, (O) Active low
private: private:
Processor::PinLevel m_RXDATA; bool selected();
Processor::PinLevel m_TXDATA;
Processor::PinLevel m_RTS; void reset();
Processor::PinLevel m_CTS;
Processor::PinLevel m_DCD;
Processor::PinLevel m_RXCLK; void step();
Processor::PinLevel m_TXCLK;
PinLevel m_RXDATA;
PinLevel m_TXDATA;
PinLevel m_RTS;
PinLevel m_CTS;
PinLevel m_DCD;
PinLevel m_RXCLK;
PinLevel m_TXCLK;
PinLevel m_CS0;
PinLevel m_CS1;
PinLevel m_CS2;
PinLevel m_RS;
PinLevel m_RW;
PinLevel m_E;
PinLevel m_IRQ;
uint8_t m_data; uint8_t m_data;
Processor::PinLevel m_CS0; // Control registers
Processor::PinLevel m_CS1; int m_counterDivide;
Processor::PinLevel m_CS2; int m_wordConfiguration;
int m_transmitterControl;
int m_receiveControl;
Processor::PinLevel m_RS; // Status registers
Processor::PinLevel m_RW; bool m_RDRF;
Processor::PinLevel m_E;
Processor::PinLevel m_IRQ;
}; };
} }

Binary file not shown.