From 8ea7bf5d68d15d0ba55d5e04d675c1a059f7a45d Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Sat, 29 Sep 2018 14:31:50 +0100 Subject: [PATCH] Refactoring on the MC6850 and associated test board code. Signed-off-by: Adrian Conlon --- MC6809/test/Board.cpp | 56 +++++++++++++++++++------------- MC6809/test/Board.h | 2 +- MC6850/inc/MC6850.h | 74 ++++++++++++++++++++++++++++++------------ MC6850/src/MC6850.cpp | Bin 4954 -> 4614 bytes 4 files changed, 88 insertions(+), 44 deletions(-) diff --git a/MC6809/test/Board.cpp b/MC6809/test/Board.cpp index 7fe5e4a..5527d7c 100644 --- a/MC6809/test/Board.cpp +++ b/MC6809/test/Board.cpp @@ -12,19 +12,29 @@ Board::Board(const Configuration& configuration) void Board::initialise() { + // Load our BASIC interpreter const auto directory = m_configuration.getRomDirectory() + "\\"; - loadHexFile(directory + "ExBasROM.hex"); - if (m_configuration.isDebugMode()) { - CPU().ExecutingInstruction.connect(std::bind(&Board::Cpu_ExecutingInstruction_Debug, this, std::placeholders::_1)); - CPU().ExecutedInstruction.connect(std::bind(&Board::Cpu_ExecutedInstruction_Debug, this, std::placeholders::_1)); - } + // Get the CPU ready for action + CPU().powerOn(); + CPU().raise(CPU().NMI()); + CPU().raise(CPU().FIRQ()); + CPU().reset(); - 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)); + // Get the ACIA ready for action + ACIA().powerOn(); + ACIA().lower(ACIA().RW()); // Write + ACIA().lower(ACIA().RS()); // Registers + ACIA().raise(ACIA().CS0()); // Chip select + ACIA().raise(ACIA().CS1()); // " + ACIA().lower(ACIA().CS2()); // " + ACIA().DATA() = EightBit::mc6850::CR0 | EightBit::mc6850::CR1; // Master reset + // Get the reset out of the way... + ACIA().step(1); + + // Once the reset has completed, we can wire the ACIA event handlers... ACIA().Accessing.connect(std::bind(&Board::Acia_Accessing, this, std::placeholders::_1)); ACIA().Accessed.connect(std::bind(&Board::Acia_Accessed, this, std::placeholders::_1)); @@ -34,16 +44,16 @@ void Board::initialise() { ACIA().Receiving.connect(std::bind(&Board::Acia_Receiving, this, std::placeholders::_1)); ACIA().Received.connect(std::bind(&Board::Acia_Received, this, std::placeholders::_1)); - CPU().powerOn(); - CPU().raise(CPU().NMI()); - CPU().raise(CPU().FIRQ()); - CPU().reset(); + // Wire bus events... + WrittenByte.connect(std::bind(&Board::Bus_WrittenByte_Acia, this, std::placeholders::_1)); + ReadingByte.connect(std::bind(&Board::Bus_ReadingByte_Acia, this, std::placeholders::_1)); - ACIA().powerOn(); - ACIA().RW() = EightBit::Chip::PinLevel::Low; // Write - ACIA().RS() = EightBit::Chip::PinLevel::Low; // Registers - EightBit::Processor::setFlag(ACIA().DATA(), EightBit::mc6850::CR0 | EightBit::mc6850::CR1); - ACIA().step(1); // Get the reset out of the way... + // Wire CPU events + CPU().ExecutedInstruction.connect(std::bind(&Board::Cpu_ExecutedInstruction_Acia, this, std::placeholders::_1)); + if (m_configuration.isDebugMode()) { + CPU().ExecutingInstruction.connect(std::bind(&Board::Cpu_ExecutingInstruction_Debug, this, std::placeholders::_1)); + CPU().ExecutedInstruction.connect(std::bind(&Board::Cpu_ExecutedInstruction_Debug, this, std::placeholders::_1)); + } } void Board::Cpu_ExecutingInstruction_Debug(EightBit::mc6809&) { @@ -76,10 +86,10 @@ EightBit::MemoryMapping Board::mapping(uint16_t address) { return { m_rom, 0xc000, EightBit::MemoryMapping::ReadOnly }; } -void Board::Bus_WritingByte_Acia(EightBit::EventArgs&) { +void Board::Bus_WrittenByte_Acia(EightBit::EventArgs&) { updateAciaPins(EightBit::Chip::Low); if (ACIA().selected()) - ACIA().DATA() = DATA(); + ACIA().DATA() = peek(ADDRESS()); } void Board::Bus_ReadingByte_Acia(EightBit::EventArgs&) { @@ -91,10 +101,10 @@ void Board::Bus_ReadingByte_Acia(EightBit::EventArgs&) { void Board::updateAciaPins(const EightBit::Chip::PinLevel rw) { ACIA().RW() = rw; 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; + ADDRESS().word & EightBit::Chip::Bit0 ? ACIA().raise(ACIA().RS()) : ACIA().lower(ACIA().RS()); + ADDRESS().word & EightBit::Chip::Bit15 ? ACIA().raise(ACIA().CS0()) : ACIA().lower(ACIA().CS0()); + ADDRESS().word & EightBit::Chip::Bit13 ? ACIA().raise(ACIA().CS1()) : ACIA().lower(ACIA().CS1()); + ADDRESS().word & EightBit::Chip::Bit14 ? ACIA().raise(ACIA().CS2()) : ACIA().lower(ACIA().CS2()); } void Board::Cpu_ExecutedInstruction_Acia(EightBit::mc6809&) { diff --git a/MC6809/test/Board.h b/MC6809/test/Board.h index b337271..7a877d2 100644 --- a/MC6809/test/Board.h +++ b/MC6809/test/Board.h @@ -53,7 +53,7 @@ private: // ACIA handling - void Bus_WritingByte_Acia(EightBit::EventArgs&); + void Bus_WrittenByte_Acia(EightBit::EventArgs&); void Bus_ReadingByte_Acia(EightBit::EventArgs&); void Cpu_ExecutedInstruction_Acia(EightBit::mc6809&); diff --git a/MC6850/inc/MC6850.h b/MC6850/inc/MC6850.h index 586c2b0..6762a91 100644 --- a/MC6850/inc/MC6850.h +++ b/MC6850/inc/MC6850.h @@ -49,24 +49,58 @@ namespace EightBit { // *** Data bit is "don't case" in 7-bit plus parity modes enum ControlRegisters { - CR0 = 0b1, - CR1 = 0b10, - CR2 = 0b100, - CR3 = 0b1000, - CR4 = 0b10000, - CR5 = 0b100000, - CR6 = 0b1000000, - CR7 = 0b10000000 + CR0 = 0b1, // Counter divide + CR1 = 0b10, // " + CR2 = 0b100, // Word select + CR3 = 0b1000, // " + CR4 = 0b10000, // " + CR5 = 0b100000, // Transmit control + CR6 = 0b1000000, // " + CR7 = 0b10000000 // Receive control }; - + + // CR0 and CR1 + enum CounterDivideSelect { + One = 0b00, + Sixteen = 0b01, + SixtyFour = 0b10, + MasterReset = 0b11 + }; + + // CR2, CR3 and CR4 + enum WordSelect { + SevenEvenTwo = 0b000, + SevenOddTwo = 0b001, + SevenEvenOne = 0b010, + SevenOddOne = 0b011, + EightTwo = 0b100, + EightOne = 0b101, + EightEvenOne = 0b110, + EightOddOne = 0b111, + }; + + // CR5 and CR6 + enum TransmitterControl { + ReadyLowInterruptDisabled = 0b00, + ReadyLowInterruptEnabled = 0b01, + ReadyHighInterruptDisabled = 0b10, + ReadyLowInterruptDisabledTransmitBreak = 0b11, + }; + + // CR7 + enum ReceiveControl { + ReceiveInterruptDisable = 0b0, + ReceiveInterruptEnable = 0b1, // Triggers on: RDR full, overrun, DCD low -> high + }; + enum StatusRegisters { - STATUS_RDRF = 0b1, - STATUS_TDRE = 0b10, - STATUS_DCD = 0b100, - STATUS_CTS = 0b1000, - STATUS_FE = 0b10000, - STATUS_OVRN = 0b100000, - STATUS_PE = 0b1000000, + STATUS_RDRF = 0b1, + STATUS_TDRE = 0b10, + STATUS_DCD = 0b100, + STATUS_CTS = 0b1000, + STATUS_FE = 0b10000, + STATUS_OVRN = 0b100000, + STATUS_PE = 0b1000000, STATUS_IRQ = 0b10000000, }; @@ -149,10 +183,10 @@ namespace EightBit { uint8_t m_data; // Control registers - int m_counterDivide; - int m_wordConfiguration; - int m_transmitControl; - int m_receiveControl; + CounterDivideSelect m_counterDivide; + WordSelect m_wordSelect; + TransmitterControl m_transmitControl; + ReceiveControl m_receiveControl; // Status registers uint8_t m_status; diff --git a/MC6850/src/MC6850.cpp b/MC6850/src/MC6850.cpp index fb6a2cb6a69b07ddbf4d78eb8d47798d21209a63..5afe40db88468d8c3fd75ce1bf563d182d4c1cdb 100644 GIT binary patch delta 753 zcmah{O-lk{5T3O*_ruKS5F)`V)uxy51N2}DrePKlt%8uJNCUwXObQAQb?6oZ^CyCi z{(?Feb?6{LLDzmmhi2ba)>bKoWrpRM=Y3}8dDSi#u6tz$E!cw^96=Q-5P%F6AVfJx z!9b%Jg$Uaab!fr~F|-C)B6#On!)GD3&EO0sK>?YYTwsQCUsV|d~Umz^PyF_F9%;Krc#3UVP3v)^>G1$ex_#YqzOK5fX*JWoZt4o|Ep3}MdDs>-I^=~J)S%&No=eA2hiqun$Z)(SDUD#$B g%*+1njVmN@GcfnNnO&$)J@ER#^J3)g#dJ^j1~~_du>b%7 literal 4954 zcmd59#Q(6xge-}XhXO{0r1A(Rs936gB(*H1u@us7X$bPy)pO?VbY{zT zYg-;>vvhZM=046n_ragv&!j1BsY^?GaxAfgGA9>!Kb04_=j5q8k-R-0WlPrNwXDjL zw=;kDJIJd^7gsDDNo3PV<=!81j;jT&JFuexjfuR+QzCD0o#C9-!FQf-;jZI*3~M7< zz{zVPEr8@0>plFo)0IF1?Aek-*rrMFjZwL_sqLifiEH+I!frLm(!1M_5r7p&TC_0ZnNJYL3 zEDiBi1$Gv>V%*g30NNA8nsMl+C+7|35hPWmjQcB|jt~{f4&@i_?3ZnP+a4ehGBGeOZ&>1Fs;H-2@Ew+&?O37)t=LIyG$+Q6fXl?Jph=VIW0fwe0WP3yVJTa-mu zqwxw6^|s-ujcm=x4RN*!DP-_*s*Cx1j;~i(<5LI?tU{qdU30RV=HUVMoe!+$DO(8= z*~R`EERA4mmUYh|E00xNS9>k1$JYbP?7Ol=@u4O9G|rN2We8Bc?gkOf_G#_#8L)>a zbWDUbnyf(VB&Vj%@K?Y0%`d;O_RxzCBFBs)cR~~Ax~bq{$_HI12YV*g%9~OlH#B#t zaT0#)g8!D?qcEOM@@M&mO8V)Zq#t;8YfS3Ev28LU^!jTbc(AWB&lSwCtfyPfP3I*hN;uS27yG+>`rM`eau>3YyCR^~h;r6%exJ3aG*er}s?SxzIQm7mj01=Ec7 zO+GJsyyCo*kL?*ex42fIL1zTj!-=5S7Fx3eE-mA-OrS1{Nxt-9pLIfW(}^$X1{yet z@vH5K)WD1O^-ZlfhWF$)dsf5L2~HYKv!=d81*olfsJ--_Ujaedx``{4m5hg~-7)73 z+LF`?uIlVce2O%$dfL`9+E#P4kzwr84xF0x_W^JG0ETPI55IU4IM