Reduced the time between reading and writing the IEC bus in 1541 mode.
Doing this increases compatability for some people using regular Pi3 models.
This commit is contained in:
parent
a25f1963c0
commit
123612a473
3 changed files with 125 additions and 126 deletions
137
src/iec_bus.cpp
137
src/iec_bus.cpp
|
@ -67,10 +67,13 @@ u32 IEC_Bus::inputRepeatPrev[5] = { 0 };
|
|||
|
||||
u32 IEC_Bus::emulationModeCheckButtonIndex = 0;
|
||||
|
||||
unsigned IEC_Bus::gplev0;
|
||||
|
||||
|
||||
void IEC_Bus::ReadBrowseMode(void)
|
||||
{
|
||||
IOPort* portB = 0;
|
||||
unsigned gplev0 = read32(ARM_GPIO_GPLEV0);
|
||||
gplev0 = read32(ARM_GPIO_GPLEV0);
|
||||
|
||||
int index;
|
||||
for (index = 0; index < buttonCount; ++index)
|
||||
|
@ -116,20 +119,20 @@ void IEC_Bus::ReadBrowseMode(void)
|
|||
Resetting = !ignoreReset && ((gplev0 & PIGPIO_MASK_IN_RESET) == (invertIECInputs ? PIGPIO_MASK_IN_RESET : 0));
|
||||
}
|
||||
|
||||
void IEC_Bus::ReadEmulationMode1541(void)
|
||||
void IEC_Bus::ReadButtonsEmulationMode(void)
|
||||
{
|
||||
IOPort* portB = 0;
|
||||
unsigned gplev0 = read32(ARM_GPIO_GPLEV0);
|
||||
|
||||
int buttonIndex;
|
||||
for (buttonIndex = 0; buttonIndex < 3; ++buttonIndex)
|
||||
{
|
||||
UpdateButton(buttonIndex, gplev0);
|
||||
}
|
||||
// Doing it this way screws with the debounce counters.
|
||||
//UpdateButton(emulationModeCheckButtonIndex, gplev0);
|
||||
//emulationModeCheckButtonIndex++;
|
||||
//emulationModeCheckButtonIndex %= buttonCount;
|
||||
}
|
||||
|
||||
void IEC_Bus::ReadEmulationMode1541(void)
|
||||
{
|
||||
bool AtnaDataSetToOutOld = AtnaDataSetToOut;
|
||||
IOPort* portB = 0;
|
||||
gplev0 = read32(ARM_GPIO_GPLEV0);
|
||||
|
||||
portB = port;
|
||||
|
||||
|
@ -156,10 +159,14 @@ void IEC_Bus::ReadEmulationMode1541(void)
|
|||
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)
|
||||
|
||||
// moved from PortB_OnPortOut
|
||||
if (AtnaDataSetToOut)
|
||||
portB->SetInput(VIAPORTPINS_DATAIN, true); // simulate the read in software
|
||||
|
||||
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)
|
||||
//if (PI_Data != DATAIn)
|
||||
{
|
||||
PI_Data = DATAIn;
|
||||
portB->SetInput(VIAPORTPINS_DATAIN, DATAIn); // VIA DATAin pb0 output from inverted DIN 5 DATA
|
||||
|
@ -174,7 +181,7 @@ void IEC_Bus::ReadEmulationMode1541(void)
|
|||
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)
|
||||
//if (PI_Clock != CLOCKIn)
|
||||
{
|
||||
PI_Clock = CLOCKIn;
|
||||
portB->SetInput(VIAPORTPINS_CLOCKIN, CLOCKIn); // VIA CLKin pb2 output from inverted DIN 4 CLK
|
||||
|
@ -192,17 +199,9 @@ void IEC_Bus::ReadEmulationMode1541(void)
|
|||
void IEC_Bus::ReadEmulationMode1581(void)
|
||||
{
|
||||
IOPort* portB = 0;
|
||||
unsigned gplev0 = read32(ARM_GPIO_GPLEV0);
|
||||
gplev0 = read32(ARM_GPIO_GPLEV0);
|
||||
|
||||
int buttonIndex;
|
||||
for (buttonIndex = 0; buttonIndex < 3; ++buttonIndex)
|
||||
{
|
||||
UpdateButton(buttonIndex, gplev0);
|
||||
}
|
||||
// Doing it this way screws with the debounce counters.
|
||||
//UpdateButton(emulationModeCheckButtonIndex, gplev0);
|
||||
//emulationModeCheckButtonIndex++;
|
||||
//emulationModeCheckButtonIndex %= buttonCount;
|
||||
ReadButtonsEmulationMode();
|
||||
|
||||
portB = port;
|
||||
|
||||
|
@ -275,3 +274,99 @@ void IEC_Bus::ReadEmulationMode1581(void)
|
|||
Resetting = !ignoreReset && ((gplev0 & PIGPIO_MASK_IN_RESET) == (invertIECInputs ? PIGPIO_MASK_IN_RESET : 0));
|
||||
}
|
||||
|
||||
void IEC_Bus::RefreshOuts1541(void)
|
||||
{
|
||||
unsigned set = 0;
|
||||
unsigned clear = 0;
|
||||
unsigned tmp;
|
||||
|
||||
if (!splitIECLines)
|
||||
{
|
||||
unsigned outputs = 0;
|
||||
|
||||
if (AtnaDataSetToOut || DataSetToOut) outputs |= (FS_OUTPUT << ((PIGPIO_DATA - 10) * 3));
|
||||
if (ClockSetToOut) outputs |= (FS_OUTPUT << ((PIGPIO_CLOCK - 10) * 3));
|
||||
|
||||
unsigned nValue = (myOutsGPFSEL1 & PI_OUTPUT_MASK_GPFSEL1) | outputs;
|
||||
write32(ARM_GPIO_GPFSEL1, nValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (AtnaDataSetToOut || DataSetToOut) set |= 1 << PIGPIO_OUT_DATA;
|
||||
else clear |= 1 << PIGPIO_OUT_DATA;
|
||||
|
||||
if (ClockSetToOut) set |= 1 << PIGPIO_OUT_CLOCK;
|
||||
else clear |= 1 << PIGPIO_OUT_CLOCK;
|
||||
|
||||
if (!invertIECOutputs) {
|
||||
tmp = set;
|
||||
set = clear;
|
||||
clear = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (OutputLED) set |= 1 << PIGPIO_OUT_LED;
|
||||
else clear |= 1 << PIGPIO_OUT_LED;
|
||||
|
||||
if (OutputSound) set |= 1 << PIGPIO_OUT_SOUND;
|
||||
else clear |= 1 << PIGPIO_OUT_SOUND;
|
||||
|
||||
write32(ARM_GPIO_GPCLR0, clear);
|
||||
write32(ARM_GPIO_GPSET0, set);
|
||||
}
|
||||
|
||||
void IEC_Bus::PortB_OnPortOut(void* pUserData, unsigned char status)
|
||||
{
|
||||
bool oldDataSetToOut = DataSetToOut;
|
||||
bool oldClockSetToOut = ClockSetToOut;
|
||||
bool AtnaDataSetToOutOld = AtnaDataSetToOut;
|
||||
|
||||
// These are the values the VIA is trying to set the outputs to
|
||||
VIA_Atna = (status & (unsigned char)VIAPORTPINS_ATNAOUT) != 0;
|
||||
VIA_Data = (status & (unsigned char)VIAPORTPINS_DATAOUT) != 0; // VIA DATAout PB1 inverted and then connected to DIN DATA
|
||||
VIA_Clock = (status & (unsigned char)VIAPORTPINS_CLOCKOUT) != 0; // VIA CLKout PB3 inverted and then connected to DIN CLK
|
||||
|
||||
if (VIA)
|
||||
{
|
||||
// Emulate the XOR gate UD3
|
||||
AtnaDataSetToOut = (VIA_Atna != PI_Atn);
|
||||
}
|
||||
else
|
||||
{
|
||||
AtnaDataSetToOut = (VIA_Atna & PI_Atn);
|
||||
}
|
||||
|
||||
//if (AtnaDataSetToOut)
|
||||
//{
|
||||
// // if the output of the XOR gate is high (ie VIA_Atna != PI_Atn) then this is inverted and pulls DATA low (activating it)
|
||||
// //PI_Data = true;
|
||||
// if (port) port->SetInput(VIAPORTPINS_DATAIN, true); // simulate the read in software
|
||||
//}
|
||||
|
||||
if (VIA && port)
|
||||
{
|
||||
// If the VIA's data and clock outputs ever get set to inputs the real hardware reads these lines as asserted.
|
||||
bool PB1SetToInput = (port->GetDirection() & 2) == 0;
|
||||
bool PB3SetToInput = (port->GetDirection() & 8) == 0;
|
||||
if (PB1SetToInput) VIA_Data = true;
|
||||
if (PB3SetToInput) VIA_Clock = true;
|
||||
}
|
||||
|
||||
ClockSetToOut = VIA_Clock;
|
||||
DataSetToOut = VIA_Data;
|
||||
|
||||
//if (!oldDataSetToOut && DataSetToOut)
|
||||
//{
|
||||
// //PI_Data = true;
|
||||
// if (port) port->SetInput(VIAPORTPINS_DATAOUT, true); // simulate the read in software
|
||||
//}
|
||||
|
||||
//if (!oldClockSetToOut && ClockSetToOut)
|
||||
//{
|
||||
// //PI_Clock = true;
|
||||
// if (port) port->SetInput(VIAPORTPINS_CLOCKIN, true); // simulate the read in software
|
||||
//}
|
||||
|
||||
//if (AtnaDataSetToOutOld ^ AtnaDataSetToOut)
|
||||
// RefreshOuts1541();
|
||||
}
|
||||
|
|
|
@ -351,6 +351,7 @@ public:
|
|||
|
||||
static void ReadBrowseMode(void);
|
||||
static void ReadEmulationMode1541(void);
|
||||
static void ReadButtonsEmulationMode(void);
|
||||
static void ReadEmulationMode1581(void);
|
||||
|
||||
static void WaitUntilReset(void)
|
||||
|
@ -369,99 +370,9 @@ public:
|
|||
}
|
||||
|
||||
// Out going
|
||||
static void PortB_OnPortOut(void* pUserData, unsigned char status)
|
||||
{
|
||||
bool oldDataSetToOut = DataSetToOut;
|
||||
bool oldClockSetToOut = ClockSetToOut;
|
||||
static void PortB_OnPortOut(void* pUserData, unsigned char status);
|
||||
|
||||
// These are the values the VIA is trying to set the outputs to
|
||||
VIA_Atna = (status & (unsigned char)VIAPORTPINS_ATNAOUT) != 0;
|
||||
VIA_Data = (status & (unsigned char)VIAPORTPINS_DATAOUT) != 0; // VIA DATAout PB1 inverted and then connected to DIN DATA
|
||||
VIA_Clock = (status & (unsigned char)VIAPORTPINS_CLOCKOUT) != 0; // VIA CLKout PB3 inverted and then connected to DIN CLK
|
||||
|
||||
if (VIA)
|
||||
{
|
||||
// Emulate the XOR gate UD3
|
||||
AtnaDataSetToOut = (VIA_Atna != PI_Atn);
|
||||
}
|
||||
else
|
||||
{
|
||||
AtnaDataSetToOut = (VIA_Atna & PI_Atn);
|
||||
}
|
||||
|
||||
if (AtnaDataSetToOut)
|
||||
{
|
||||
// if the output of the XOR gate is high (ie VIA_Atna != PI_Atn) then this is inverted and pulls DATA low (activating it)
|
||||
PI_Data = true;
|
||||
if (port) port->SetInput(VIAPORTPINS_DATAIN, true); // simulate the read in software
|
||||
}
|
||||
|
||||
if (VIA && port)
|
||||
{
|
||||
// If the VIA's data and clock outputs ever get set to inputs the real hardware reads these lines as asserted.
|
||||
bool PB1SetToInput = (port->GetDirection() & 2) == 0;
|
||||
bool PB3SetToInput = (port->GetDirection() & 8) == 0;
|
||||
if (PB1SetToInput) VIA_Data = true;
|
||||
if (PB3SetToInput) VIA_Clock = true;
|
||||
}
|
||||
|
||||
ClockSetToOut = VIA_Clock;
|
||||
DataSetToOut = VIA_Data;
|
||||
|
||||
if (!oldDataSetToOut && DataSetToOut)
|
||||
{
|
||||
PI_Data = true;
|
||||
if (port) port->SetInput(VIAPORTPINS_DATAOUT, true); // simulate the read in software
|
||||
}
|
||||
|
||||
if (!oldClockSetToOut && ClockSetToOut)
|
||||
{
|
||||
PI_Clock = true;
|
||||
if (port) port->SetInput(VIAPORTPINS_CLOCKIN, true); // simulate the read in software
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static inline void RefreshOuts1541(void)
|
||||
{
|
||||
unsigned set = 0;
|
||||
unsigned clear = 0;
|
||||
unsigned tmp;
|
||||
|
||||
if (!splitIECLines)
|
||||
{
|
||||
unsigned outputs = 0;
|
||||
|
||||
if (AtnaDataSetToOut || DataSetToOut) outputs |= (FS_OUTPUT << ((PIGPIO_DATA - 10) * 3));
|
||||
if (ClockSetToOut) outputs |= (FS_OUTPUT << ((PIGPIO_CLOCK - 10) * 3));
|
||||
|
||||
unsigned nValue = (myOutsGPFSEL1 & PI_OUTPUT_MASK_GPFSEL1) | outputs;
|
||||
write32(ARM_GPIO_GPFSEL1, nValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (AtnaDataSetToOut || DataSetToOut) set |= 1 << PIGPIO_OUT_DATA;
|
||||
else clear |= 1 << PIGPIO_OUT_DATA;
|
||||
|
||||
if (ClockSetToOut) set |= 1 << PIGPIO_OUT_CLOCK;
|
||||
else clear |= 1 << PIGPIO_OUT_CLOCK;
|
||||
|
||||
if (!invertIECOutputs) {
|
||||
tmp = set;
|
||||
set = clear;
|
||||
clear = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (OutputLED) set |= 1 << PIGPIO_OUT_LED;
|
||||
else clear |= 1 << PIGPIO_OUT_LED;
|
||||
|
||||
if (OutputSound) set |= 1 << PIGPIO_OUT_SOUND;
|
||||
else clear |= 1 << PIGPIO_OUT_SOUND;
|
||||
|
||||
write32(ARM_GPIO_GPSET0, set);
|
||||
write32(ARM_GPIO_GPCLR0, clear);
|
||||
}
|
||||
static void RefreshOuts1541(void);
|
||||
|
||||
static inline void RefreshOuts1581(void)
|
||||
{
|
||||
|
@ -697,6 +608,8 @@ private:
|
|||
|
||||
static u32 emulationModeCheckButtonIndex;
|
||||
|
||||
static unsigned gplev0;
|
||||
|
||||
static bool PI_Atn;
|
||||
static bool PI_Data;
|
||||
static bool PI_Clock;
|
||||
|
|
17
src/main.cpp
17
src/main.cpp
|
@ -724,7 +724,8 @@ EXIT_TYPE Emulate1541(FileBrowser* fileBrowser)
|
|||
//read32(ARM_SYSTIMER_CLO); //Each one of these is > 100ns
|
||||
//read32(ARM_SYSTIMER_CLO);
|
||||
//read32(ARM_SYSTIMER_CLO);
|
||||
//IEC_Bus::RefreshOuts(); // Now output all outputs.
|
||||
|
||||
IEC_Bus::RefreshOuts1541(); // Now output all outputs.
|
||||
|
||||
IEC_Bus::OutputLED = pi1541.drive.IsLEDOn();
|
||||
if (IEC_Bus::OutputLED ^ oldLED)
|
||||
|
@ -749,21 +750,11 @@ EXIT_TYPE Emulate1541(FileBrowser* fileBrowser)
|
|||
}
|
||||
}
|
||||
|
||||
//if (options.SoundOnGPIO() && headSoundCounter > 0)
|
||||
//{
|
||||
// headSoundFreqCounter--; // Continue updating a GPIO non DMA sound.
|
||||
// if (headSoundFreqCounter <= 0)
|
||||
// {
|
||||
// headSoundFreqCounter = headSoundFreq;
|
||||
// headSoundCounter -= headSoundFreq * 8;
|
||||
// IEC_Bus::OutputSound = !IEC_Bus::OutputSound;
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
IEC_Bus::RefreshOuts1541(); // Now output all outputs.
|
||||
}
|
||||
|
||||
IEC_Bus::ReadButtonsEmulationMode();
|
||||
|
||||
// Other core will check the uart (as it is slow) (could enable uart irqs - will they execute on this core?)
|
||||
inputMappings->CheckKeyboardEmulationMode(numberOfImages, numberOfImagesMax);
|
||||
inputMappings->CheckButtonsEmulationMode();
|
||||
|
|
Loading…
Reference in a new issue