From b3faa0bb2e425b8d475d07c0e9e14cc27bbfc439 Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Sun, 23 Sep 2018 13:14:10 +0100 Subject: [PATCH] Wire the MC6850 chip into the MC6809 test code. Signed-off-by: Adrian Conlon --- MC6809/test/Board.cpp | 48 ++++++++------ MC6809/test/Board.h | 16 ++++- MC6809/test/test_MC6809.vcxproj | 11 ++-- MC6850/inc/MC6850.h | 110 ++++++++++++++++++++++---------- MC6850/src/MC6850.cpp | Bin 80 -> 1980 bytes 5 files changed, 124 insertions(+), 61 deletions(-) diff --git a/MC6809/test/Board.cpp b/MC6809/test/Board.cpp index a0aaec9..cbd105c 100644 --- a/MC6809/test/Board.cpp +++ b/MC6809/test/Board.cpp @@ -23,13 +23,16 @@ void Board::initialise() { CPU().ExecutedInstruction.connect(std::bind(&Board::Cpu_ExecutedInstruction_die, this, std::placeholders::_1)); - //WrittenByte.connect(std::bind(&Board::Bus_WrittenByte, this, std::placeholders::_1)); - //ReadingByte.connect(std::bind(&Board::Bus_ReadingByte, this, std::placeholders::_1)); + WritingByte.connect(std::bind(&Board::Bus_WritingByte_Acia, 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().raise(CPU().NMI()); CPU().raise(CPU().FIRQ()); CPU().reset(); + + ACIA().powerOn(); } 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; } -void Board::Cpu_ExecutedInstruction_die(EightBit::mc6809& cpu) { +void Board::Cpu_ExecutedInstruction_die(EightBit::mc6809&) { static uint64_t instructions = 0UL; if (++instructions > 90000000) - 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); - } - } + CPU().powerOff(); } 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 }; } + +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()); +} \ No newline at end of file diff --git a/MC6809/test/Board.h b/MC6809/test/Board.h index d81b578..c21c60f 100644 --- a/MC6809/test/Board.h +++ b/MC6809/test/Board.h @@ -8,12 +8,14 @@ #include #include #include +#include class Board : public EightBit::Bus { public: Board(const Configuration& configuration); EightBit::mc6809& CPU() { return m_cpu; } + EightBit::mc6850& ACIA() { return m_acia; } void initialise(); @@ -36,6 +38,8 @@ private: EightBit::Ram m_io = 0x2000; // A000 - BFFF, 8K serial interface, minimally decoded EightBit::Rom m_rom = 0x4000; // C000 - FFFF, 16K ROM + EightBit::mc6850 m_acia; + EightBit::mc6809 m_cpu; EightBit::Disassembly m_disassembler; @@ -47,8 +51,14 @@ private: void Cpu_ExecutingInstruction_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&); - void Bus_ReadingByte(EightBit::EventArgs&); + // ACIA handling + + void Bus_WritingByte_Acia(EightBit::EventArgs&); + void Bus_ReadingByte_Acia(EightBit::EventArgs&); + + void Cpu_ExecutedInstruction_Acia(EightBit::mc6809&); + + void updateAciaPins(); }; diff --git a/MC6809/test/test_MC6809.vcxproj b/MC6809/test/test_MC6809.vcxproj index bc26e53..f1fdbfa 100644 --- a/MC6809/test/test_MC6809.vcxproj +++ b/MC6809/test/test_MC6809.vcxproj @@ -71,19 +71,19 @@ false - ..\inc;..\..\inc;C:\Libraries\boost_1_65_1;$(IncludePath) + ..\inc;..\..\inc;..\..\MC6850\inc;C:\Libraries\boost_1_65_1;$(IncludePath) true - ..\inc;..\..\inc;C:\Libraries\boost_1_65_1;$(IncludePath) + ..\inc;..\..\inc;..\..\MC6850\inc;C:\Libraries\boost_1_65_1;$(IncludePath) true - ..\inc;..\..\inc;C:\Libraries\boost_1_65_1;$(IncludePath) + ..\inc;..\..\inc;..\..\MC6850\inc;C:\Libraries\boost_1_65_1;$(IncludePath) false - ..\inc;..\..\inc;C:\Libraries\boost_1_65_1;$(IncludePath) + ..\inc;..\..\inc;..\..\MC6850\inc;C:\Libraries\boost_1_65_1;$(IncludePath) @@ -167,6 +167,9 @@ + + {a4ada650-55c3-4c00-8dad-e4e4aff86eff} + {a9c24bd9-0cb4-4c84-b09b-46b815f9da47} diff --git a/MC6850/inc/MC6850.h b/MC6850/inc/MC6850.h index 42a0c23..dce918e 100644 --- a/MC6850/inc/MC6850.h +++ b/MC6850/inc/MC6850.h @@ -2,10 +2,10 @@ #include -#include +#include namespace EightBit { - class mc6850 { + class mc6850 : public Chip { public: // +--------+----------------------------------------------------------------------------------+ // | | Buffer address | @@ -14,10 +14,10 @@ namespace EightBit { // | Data | RS * R/W | RS * R/W | RS * R/W | RS * R/W | // | Bus | (high)(low) | (high)(high) | (low)(low) | (low)(low) | // | Line | Transmit | Receive | | | - // | Number | Data | Data | Control | Control | - // | | Register | Register | register | register | + // | Number | Data | Data | Control | Status | + // | | Register | Register | register | register | // | +------------------+------------------+--------------------+-----------------------+ - // | | (Write only) + (Read only) + (Write only) | (Read only) | + // | | (Write only) + (Read only) + (Write only) | (Read only) | // +--------+------------------+------------------+--------------------+-----------------------+ // | 0 | Data bit 0* | Data bit 0 | Counter divide | Receive data register | // | | | | select 1 (CR0) | full (RDRF) | @@ -47,49 +47,89 @@ namespace EightBit { // ** Data bit will be zero 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 - Processor::PinLevel& TXDATA() { return m_TXDATA; } // Transmit data, (O) Active high + enum ControlRegisters { + CR0 = 0b1, + CR1 = 0b10, + CR2 = 0b100, + CR3 = 0b1000, + CR4 = 0b10000, + CR5 = 0b100000, + CR6 = 0b1000000, + CR7 = 0b10000000 + }; + + enum StatusRegisters { + RDRF = 0b1, + TDRE = 0b10, + kDCD = 0b100, + kCTS = 0b1000, + FE = 0b10000, + OVRN = 0b100000, + PE = 0b1000000, + kIRQ = 0b10000000, + }; - Processor::PinLevel& RTS() { return m_RTS; } // Request to send, (O) Active low - Processor::PinLevel& CTS() { return m_CTS; } // Clear to send, (I) Active low - Processor::PinLevel& DCD() { return m_DCD; } // Data carrier detect, (I) Active low + PinLevel& RXDATA() { return m_RXDATA; } // Receive data, (I) Active high + PinLevel& TXDATA() { return m_TXDATA; } // Transmit data, (O) Active high - Processor::PinLevel& RXCLK() { return m_RXCLK; } // Transmit clock, (I) Active high - Processor::PinLevel& TXCLK() { return m_TXCLK; } // Receive clock, (I) 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 - uint8_t& DATA() { return m_data; } // Data, (I/O) + PinLevel& RXCLK() { return m_RXCLK; } // Transmit clock, (I) Active high + PinLevel& TXCLK() { return m_TXCLK; } // Receive clock, (I) Active high - Processor::PinLevel& CS0() { return m_CS0; } // Chip select, bit 0, (I) Active high - 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 + 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 - Processor::PinLevel& E() { return m_E; } // ACIA Enable, (I) Active high - Processor::PinLevel& IRQ() { return m_IRQ; } // Interrupt request, (O) 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) + + void step(int cycles); private: - Processor::PinLevel m_RXDATA; - Processor::PinLevel m_TXDATA; + bool selected(); - Processor::PinLevel m_RTS; - Processor::PinLevel m_CTS; - Processor::PinLevel m_DCD; + void reset(); - Processor::PinLevel m_RXCLK; - Processor::PinLevel m_TXCLK; + void step(); + + 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; - Processor::PinLevel m_CS0; - Processor::PinLevel m_CS1; - Processor::PinLevel m_CS2; + // Control registers + int m_counterDivide; + int m_wordConfiguration; + int m_transmitterControl; + int m_receiveControl; - Processor::PinLevel m_RS; - Processor::PinLevel m_RW; - - Processor::PinLevel m_E; - Processor::PinLevel m_IRQ; + // Status registers + bool m_RDRF; }; } diff --git a/MC6850/src/MC6850.cpp b/MC6850/src/MC6850.cpp index 749b059e9b255eb78f7fce2fc908120bfe63d0d1..262a0f38195194931746946d830651ee5b422df3 100644 GIT binary patch literal 1980 zcmb_d?@Jp&6r8VD@PD{ikc2|fw9(S4&}zXC7K#e}SmJp}4`LdUOG0V=*VUPQIqz+a zrmbb!+^>Bz^X9$X++06Lfgv&sFvSIOq*%v@&)@Kpa~*4VhGlC$;Q-rsgAO*`%H^wf ziPy!1BgYse_5-Tcp5r^mfUF;>qff>XA9z>dEypF}Dh@p>e!!XWdrq}Yv>5p_pe01k z`F_glaPcNV!ZimtrAAx3hdoAo4mlrl{fu)ExQ-V5t-II_Y~00fJu$w$GX9u8%$d)- zz<(8f<kl_cXYA}hs?@{HL-|LkHpXBu> zGfEksVwcm$>-`Ikf=J3#)v6hv>V!wCdc;@?^vK*qgL4#IS69~kq`Id|d#&Y^`fjtD z8G1&`Q=i7sbO@P!K0!4G$(b%o(4bZ;59lyuo49=pL_@{Fq$3Z+jB z^KHy)rSkN@s4S_c8=UEpX<mUNrdpJHOXl)$IN%e*z@bZ?%oHkJltTSH1=>r=hE* z=8%yyPCEfrokP6G8K+gqdO~N(2|GH)FHYTWv3^x`)V~$~Y6jaI=R^=j)uF=BP@eTZ z_6+ek=fBu4w|Mc-!=AjLPIXO>+WO&i?1nznJF9T>kzCs@*H`ZTH8o51K1YgntlZTLEoZ7W`kJN~UXTP`6^Ay4W delta 5 McmdnPA21;R00vC~`~Uy|