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 fb6a2cb..5afe40d 100644 Binary files a/MC6850/src/MC6850.cpp and b/MC6850/src/MC6850.cpp differ