From f1623f64c65caacbe0cefb8be57fb22d70e6029a Mon Sep 17 00:00:00 2001 From: Stephen White Date: Sun, 3 Jun 2018 17:43:36 +1000 Subject: [PATCH] Optimised and improved compatability for inverted split lines hardware configuration. --- src/iec_bus.cpp | 68 ++++++++++++++++++++++++++++++++++++++------ src/iec_bus.h | 7 +++-- src/iec_commands.cpp | 12 ++++---- src/main.cpp | 11 ++----- 4 files changed, 73 insertions(+), 25 deletions(-) diff --git a/src/iec_bus.cpp b/src/iec_bus.cpp index f97ed3f..75ab9c3 100644 --- a/src/iec_bus.cpp +++ b/src/iec_bus.cpp @@ -18,6 +18,8 @@ #include "iec_bus.h" +static int buttonCount = sizeof(ButtonPinFlags) / sizeof(unsigned); + u32 IEC_Bus::PIGPIO_MASK_IN_ATN = 1 << PIGPIO_ATN; u32 IEC_Bus::PIGPIO_MASK_IN_DATA = 1 << PIGPIO_DATA; u32 IEC_Bus::PIGPIO_MASK_IN_CLOCK = 1 << PIGPIO_CLOCK; @@ -58,26 +60,74 @@ u32 IEC_Bus::inputRepeatPrev[5]; m6522* IEC_Bus::VIA = 0; -void IEC_Bus::Read(void) +u32 IEC_Bus::emulationModeCheckButtonIndex = 0; + +void IEC_Bus::ReadBrowseMode(void) { IOPort* portB = 0; unsigned gplev0 = read32(ARM_GPIO_GPLEV0); int index; - int buttonCount = sizeof(ButtonPinFlags) / sizeof(unsigned); for (index = 0; index < buttonCount; ++index) { UpdateButton(index, gplev0); } - if (VIA) portB = VIA->GetPortB(); + bool ATNIn = (gplev0 & PIGPIO_MASK_IN_ATN) == (invertIECInputs ? PIGPIO_MASK_IN_ATN : 0); + if (PI_Atn != ATNIn) + { + PI_Atn = ATNIn; + } + + if (portB && (portB->GetDirection() & 0x10) == 0) + AtnaDataSetToOut = false; // If the ATNA PB4 gets set to an input then we can't be pulling data low. (Maniac Mansion does this) + + if (!AtnaDataSetToOut && !DataSetToOut) // only sense if we have not brought the line low (because we can't as we have the pin set to output but we can simulate in software) + { + bool DATAIn = (gplev0 & PIGPIO_MASK_IN_DATA) == (invertIECInputs ? PIGPIO_MASK_IN_DATA : 0); + if (PI_Data != DATAIn) + { + PI_Data = DATAIn; + } + } + else + { + PI_Data = true; + } + + if (!ClockSetToOut) // only sense if we have not brought the line low (because we can't as we have the pin set to output but we can simulate in software) + { + bool CLOCKIn = (gplev0 & PIGPIO_MASK_IN_CLOCK) == (invertIECInputs ? PIGPIO_MASK_IN_CLOCK : 0); + if (PI_Clock != CLOCKIn) + { + PI_Clock = CLOCKIn; + } + } + else + { + PI_Clock = true; + } + + Resetting = !ignoreReset && ((gplev0 & PIGPIO_MASK_IN_RESET) == (invertIECInputs ? PIGPIO_MASK_IN_RESET : 0)); +} + +void IEC_Bus::ReadEmulationMode(void) +{ + IOPort* portB = 0; + unsigned gplev0 = read32(ARM_GPIO_GPLEV0); + + UpdateButton(emulationModeCheckButtonIndex, gplev0); + emulationModeCheckButtonIndex++; + emulationModeCheckButtonIndex %= buttonCount; + + portB = VIA->GetPortB(); bool ATNIn = (gplev0 & PIGPIO_MASK_IN_ATN) == (invertIECInputs ? PIGPIO_MASK_IN_ATN : 0); if (PI_Atn != ATNIn) { PI_Atn = ATNIn; - if (VIA) + //if (VIA) { if ((portB->GetDirection() & 0x10) != 0) { @@ -100,28 +150,28 @@ void IEC_Bus::Read(void) if (PI_Data != DATAIn) { PI_Data = DATAIn; - if (VIA) portB->SetInput(VIAPORTPINS_DATAIN, DATAIn); // VIA DATAin pb0 output from inverted DIN 5 DATA + portB->SetInput(VIAPORTPINS_DATAIN, DATAIn); // VIA DATAin pb0 output from inverted DIN 5 DATA } } else { PI_Data = true; - if (VIA) portB->SetInput(VIAPORTPINS_DATAIN, true); // simulate the read in software + portB->SetInput(VIAPORTPINS_DATAIN, true); // simulate the read in software } if (!ClockSetToOut) // only sense if we have not brought the line low (because we can't as we have the pin set to output but we can simulate in software) { - bool CLOCKIn = (gplev0 & PIGPIO_MASK_IN_CLOCK) == (invertIECInputs ? PIGPIO_MASK_IN_CLOCK : 0); + bool CLOCKIn = (gplev0 & PIGPIO_MASK_IN_CLOCK) == (invertIECInputs ? PIGPIO_MASK_IN_CLOCK : 0); if (PI_Clock != CLOCKIn) { PI_Clock = CLOCKIn; - if (VIA) portB->SetInput(VIAPORTPINS_CLOCKIN, CLOCKIn); // VIA CLKin pb2 output from inverted DIN 4 CLK + portB->SetInput(VIAPORTPINS_CLOCKIN, CLOCKIn); // VIA CLKin pb2 output from inverted DIN 4 CLK } } else { PI_Clock = true; - if (VIA) portB->SetInput(VIAPORTPINS_CLOCKIN, true); // simulate the read in software + portB->SetInput(VIAPORTPINS_CLOCKIN, true); // simulate the read in software } Resetting = !ignoreReset && ((gplev0 & PIGPIO_MASK_IN_RESET) == (invertIECInputs ? PIGPIO_MASK_IN_RESET : 0)); diff --git a/src/iec_bus.h b/src/iec_bus.h index c98cb1e..3e6d645 100644 --- a/src/iec_bus.h +++ b/src/iec_bus.h @@ -328,7 +328,8 @@ public: } } - static void Read(void); + static void ReadBrowseMode(void); + static void ReadEmulationMode(void); static void WaitUntilReset(void) { @@ -507,7 +508,7 @@ public: { while (IsAtnAsserted()) { - Read(); + ReadBrowseMode(); } } /////////////////////////////////////////////////////////////////////////////////////////////// @@ -600,6 +601,8 @@ private: static u32 PIGPIO_MASK_IN_SRQ; static u32 PIGPIO_MASK_IN_RESET; + static u32 emulationModeCheckButtonIndex; + static bool PI_Atn; static bool PI_Data; static bool PI_Clock; diff --git a/src/iec_commands.cpp b/src/iec_commands.cpp index 7de995a..7f26b1b 100644 --- a/src/iec_commands.cpp +++ b/src/iec_commands.cpp @@ -50,7 +50,7 @@ extern unsigned versionMinor; #define WaitWhile(checkStatus) \ do\ {\ - IEC_Bus::Read();\ + IEC_Bus::ReadBrowseMode();\ if (CheckATN()) return true;\ } while (checkStatus) @@ -367,7 +367,7 @@ bool IEC_Commands::ReadIECSerialPort(u8& byte) timer.Start(200); do { - IEC_Bus::Read(); + IEC_Bus::ReadBrowseMode(); if (CheckATN()) return true; } while (IEC_Bus::IsClockReleased() && !timer.Tick()); @@ -396,7 +396,7 @@ void IEC_Commands::SimulateIECBegin(void) { SetHeaderVersion(); Reset(); - IEC_Bus::Read(); + IEC_Bus::ReadBrowseMode(); } // Paraphrasing Jim Butterfield @@ -432,7 +432,7 @@ IEC_Commands::UpdateAction IEC_Commands::SimulateIECUpdate(void) do { //DEBUG_LOG("Reset during SimulateIECUpdate\r\n"); - IEC_Bus::Read(); + IEC_Bus::ReadBrowseMode(); IEC_Bus::WaitMicroSeconds(100); } while (IEC_Bus::IsReset()); @@ -444,7 +444,7 @@ IEC_Commands::UpdateAction IEC_Commands::SimulateIECUpdate(void) switch (atnSequence) { case ATN_SEQUENCE_IDLE: - IEC_Bus::Read(); + IEC_Bus::ReadBrowseMode(); if (IEC_Bus::IsAtnAsserted()) atnSequence = ATN_SEQUENCE_ATN; else if (selectedImageName[0] != 0) updateAction = IMAGE_SELECTED; break; @@ -462,7 +462,7 @@ IEC_Commands::UpdateAction IEC_Commands::SimulateIECUpdate(void) // TODO: should set a timer here and if it times out (before the clock is released) go back to IDLE? while (IEC_Bus::IsClockReleased()) { - IEC_Bus::Read(); + IEC_Bus::ReadBrowseMode(); } break; case ATN_SEQUENCE_RECEIVE_COMMAND_CODE: diff --git a/src/main.cpp b/src/main.cpp index 1ebf65b..2b3e787 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -745,7 +745,7 @@ void emulator() while (1) { - IEC_Bus::Read(); + IEC_Bus::ReadEmulationMode(); if (pi1541.m6502.SYNC()) // About to start a new instruction. { @@ -833,12 +833,7 @@ void emulator() bool nextDisk = inputMappings->NextDisk(); bool prevDisk = inputMappings->PrevDisk(); - if (exitEmulation) - { - emulating = false; - break; - } - else if (nextDisk) + if (nextDisk) { pi1541.drive.Insert(diskCaddy.PrevDisk()); } @@ -864,7 +859,7 @@ void emulator() } bool reset = IEC_Bus::IsReset(); - if (reset) + if (reset || exitEmulation) { // Clearing the caddy now // - will write back all changed/dirty/written to disk images now